c++ 模板函数作为同一类中其他模板函数的参数1

mmvthczy  于 2023-06-25  发布在  其他
关注(0)|答案(2)|浏览(181)

我的目标是创建一个函数,在所有的“操作”函数中,以第三个参数,*类中的其他函数。假设我们有4个模板函数,分别求和(doAdd)、减(doSub)、乘(doMul)和除(doDiv)2个数字,无论它们的类型是什么。

  1. // FunctionPointers.hh
  2. namespace FunctionPointers {
  3. class FunctionPointer {
  4. public:
  5. //// Operative functions ////
  6. template<typename T, typename U>
  7. T doAdd(T& a, U& b) { T res; return res = a + b; }
  8. template<typename T, typename U>
  9. T doSub(T& a, U& b) { T res; return res = a - b; }
  10. template<typename T, typename U>
  11. T doMUl(T& a, U& b) { T res; return res = a * b; }
  12. template<typename T, typename U>
  13. T doDiv(T& a, U& b) {
  14. T res;
  15. if (b == 0) return false;
  16. return res = a / b;
  17. }
  18. };
  19. }

用例将是:

  1. // FunctionPointers.cpp
  2. #inlcude <iostream>
  3. using std::cout;
  4. using std::endl;
  5. FunctionPointers::FunctionPointer* FP = new FunctionPointers::FunctionPointer();
  6. int main() {
  7. int a = 1; float b = 3.1415;
  8. cout << FP->doAdd(a, b) << endl;
  9. cout << FP->doSub(a, b) << endl;
  10. // Something the likes of this
  11. cout << FP->doOp(a, b, doAdd) << endl;
  12. return 1;
  13. }

解决这类问题的最佳方法是什么?是否存在与写入头文件和主文件兼容的解决方案?

bmp9r5qi

bmp9r5qi1#

你也许会

  1. template<typename T, typename U, typename F>
  2. T doOp(T& a, U& b, F f)
  3. {
  4. return std::invoke(f, this, a, b);
  5. }

然后呢

  1. int main() {
  2. FunctionPointers::FunctionPointer FP;
  3. int a = 1; float b = 3.1415;
  4. std::cout << FP.doAdd(a, b) << std::endl;
  5. std::cout << FP.doSub(a, b) << std::endl;
  6. // Something the likes of this
  7. std::cout << FP.doOp(a, b, &FunctionPointers::FunctionPointer::doAdd<int, float>) << std::endl;

Demo

展开查看全部
jyztefdp

jyztefdp2#

您可以做的一件事是将地址发送到您想要调用的成员函数模板,但您最好直接调用它。
你可以做的另一件事是有一些标志,例如:

  1. enum class op {
  2. add, sub, mul, div
  3. };

然后是一个处理标志的函数

  1. template <auto O, class A, class B>
  2. auto doOp(A a, B b)
  3. {
  4. switch (O) {
  5. case op::add: return doAdd(a, b);
  6. case op::sub: return doSub(a, b);
  7. case op::mul: return doMUl(a, b);
  8. case op::div: return doDiv(a, b);
  9. }
  10. }

然后这样使用

  1. FunctionPointers::FunctionPointer FP;
  2. std::cout << FP.doOp<op::add>(a, b);

但你还是直接去做吧

  1. namespace FunctionPointers {
  2. class FunctionPointer {
  3. public:
  4. // ...
  5. template <class T, class A, class B>
  6. auto Do(A a, B b)
  7. {
  8. return T{}.operator()(a, b);
  9. }
  10. };
  11. } // namespace FunctionPointers
  12. int main()
  13. {
  14. int a = 1;
  15. float b = 3.1415;
  16. FunctionPointers::FunctionPointer FP;
  17. cout << FP.Do<std::divides<>>(a, b);
  18. }
展开查看全部

相关问题