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

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

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

// 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; 
            }
    };
}

用例将是:

// 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;
}

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

bmp9r5qi

bmp9r5qi1#

你也许会

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;

Demo

jyztefdp

jyztefdp2#

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

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);
}

相关问题