英文:
Template function taking as argument 1 of the other template functions inside same class
问题
我要翻译的部分如下:
"The objective I'm aiming to is creating a function, among all the "operative" functions, that takes as 3rd argument, one of the other functions inside the class. Say we have 4 template functions that respectively sum(doAdd
), subtract(doSub
), multiply(doMul
) and divide(doDiv
) 2 numbers, whichever their type may be."
// FunctionPointers.hh
namespace FunctionPointers {
class FunctionPointer {
public:
//// Operative functions ////
template<typename T, typename U>
T doAdd(T& a, U& b) { T res; return res = a + b; }
template<typename T, typename U>
T doSub(T& a, U& b) { T res; return res = a - b; }
template<typename T, typename U>
T doMUl(T& a, U& b) { T res; return res = a * b; }
template<typename T, typename U>
T doDiv(T& a, U& b) {
T res;
if (b == 0) return false;
return res = a / b;
}
};
}
A use case would be:
// FunctionPointers.cpp
#inlcude <iostream>
using std::cout;
using std::endl;
FunctionPointers::FunctionPointer* FP = new FunctionPointers::FunctionPointer();
int main() {
int a = 1; float b = 3.1415;
cout << FP->doAdd(a, b) << endl;
cout << FP->doSub(a, b) << endl;
// Something the likes of this
cout << FP->doOp(a, b, doAdd) << endl;
return 1;
}
What is the best approach to such problem? Does a solution even exist that is compatible with the written header and main file?
英文:
The objective I'm aiming to is creating a function, among all the "operative" functions, that takes as 3rd argument, one of the other functions inside the class. Say we have 4 template functions that respectively sum(doAdd
), subtract(doSub
), multiply(doMul
) and divide(doDiv
) 2 numbers, whichever their type may be.
// FunctionPointers.hh
namespace FunctionPointers {
class FunctionPointer {
public:
//// Operative functions ////
template<typename T, typename U>
T doAdd(T& a, U& b) { T res; return res = a + b; }
template<typename T, typename U>
T doSub(T& a, U& b) { T res; return res = a - b; }
template<typename T, typename U>
T doMUl(T& a, U& b) { T res; return res = a * b; }
template<typename T, typename U>
T doDiv(T& a, U& b) {
T res;
if (b == 0) return false;
return res = a / b;
}
};
}
A use case would be:
// FunctionPointers.cpp
#inlcude <iostream>
using std::cout;
using std::endl;
FunctionPointers::FunctionPointer* FP = new FunctionPointers::FunctionPointer();
int main() {
int a = 1; float b = 3.1415;
cout << FP->doAdd(a, b) << endl;
cout << FP->doSub(a, b) << endl;
// Something the likes of this
cout << FP->doOp(a, b, doAdd) << endl;
return 1;
}
What is the best approach to such problem? Does a solution even exist that is compatible with the written header and main file?
答案1
得分: 1
template<typename T, typename U, typename F>
T doOp(T& a, U& b, F f)
{
return std::invoke(f, this, a, b);
}
int main() {
FunctionPointers::FunctionPointer FP;
int a = 1; float b = 3.1415;
std::cout << FP.doAdd(a, b) << std::endl;
std::cout << FP.doSub(a, b) << std::endl;
// Something the likes of this
std::cout << FP.doOp(a, b, &FunctionPointers::FunctionPointer::doAdd<int, float>) << std::endl;
}
<details>
<summary>英文:</summary>
You might do
template<typename T, typename U, typename F>
T doOp(T& a, U& b, F f)
{
return std::invoke(f, this, a, b);
}
And then
int main() {
FunctionPointers::FunctionPointer FP;
int a = 1; float b = 3.1415;
std::cout << FP.doAdd(a, b) << std::endl;
std::cout << FP.doSub(a, b) << std::endl;
// Something the likes of this
std::cout << FP.doOp(a, b, &FunctionPointers::FunctionPointer::doAdd<int, float>) << std::endl;
[Demo](https://godbolt.org/z/3Kf8G6oTo)
</details>
# 答案2
**得分**: 1
你可以做的另一件事情是将地址发送给你想要调用的成员函数模板,但那么你可能就直接调用它了。
另一件事情是可以设置一些标志,例如:
```cpp
enum class op {
add, sub, mul, div
};
然后有一个处理这些标志的函数:
template <auto O, class A, class B>
auto doOp(A a, B b)
{
switch (O) {
case op::add: return doAdd(a, b);
case op::sub: return doSub(a, b);
case op::mul: return doMul(a, b);
case op::div: return doDiv(a, b);
}
}
然后像这样使用它:
FunctionPointers::FunctionPointer FP;
std::cout << FP.doOp<op::add>(a, b);
但你也可以这样做:
namespace FunctionPointers {
class FunctionPointer {
public:
// ...
template <class T, class A, class B>
auto Do(A a, B b)
{
return T{}.operator()(a, b);
}
};
} // namespace FunctionPointers
int main()
{
int a = 1;
float b = 3.1415;
FunctionPointers::FunctionPointer FP;
cout << FP.Do<std::divides<>>(a, b);
}
英文:
One thing you could do is sending the address to the member function template you want to call, but then you might as well just call it directly.
Another thing you could do is having some flags, ex:
enum class op {
add, sub, mul, div
};
and then a function to handle the flags
template <auto O, class A, class B>
auto doOp(A a, B b)
{
switch (O) {
case op::add: return doAdd(a, b);
case op::sub: return doSub(a, b);
case op::mul: return doMUl(a, b);
case op::div: return doDiv(a, b);
}
}
and use it like so
FunctionPointers::FunctionPointer FP;
std::cout << FP.doOp<op::add>(a, b);
But then you might as well just do
namespace FunctionPointers {
class FunctionPointer {
public:
// ...
template <class T, class A, class B>
auto Do(A a, B b)
{
return T{}.operator()(a, b);
}
};
} // namespace FunctionPointers
int main()
{
int a = 1;
float b = 3.1415;
FunctionPointers::FunctionPointer FP;
cout << FP.Do<std::divides<>>(a, b);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论