c++ 如何用两个模板参数重载类方法,这样我就可以使用std::function作为其中之一?

li9yvcax  于 2022-11-27  发布在  其他
关注(0)|答案(1)|浏览(122)

我需要一些关于模板的帮助。我有这样的代码,它是一个类,包含两个std::function对象的向量,以及一个将一些函数(bind、lambda或functor)推入其中一个向量的方法:

typedef std::function<int(int)> unFuncPtr;
typedef std::function<int(int, int)> binFuncPtr;

class Operations
{
public:
    template <size_t argsCount, class T>
    void RegisterOperator(T fn) {
        if (argsCount == 1) {
            m_unaryOperations.push_back(fn);
        }
        if (argsCount == 2) {
            m_binaryOperations.push_back(fn);
        }
    }

private:
    std::vector<unFuncPtr> m_binaryOperations;
    std::vector<binFuncPtr> m_unaryOperations;

例如,我希望这段代码将m_binaryOperations中有两个参数的lambda或只有一个参数的lambda推送到m_unaryOperations,调用方法RegisterOperator,如下所示:

Operations operations;
operations.RegisterOperator<1>([](int x) {return x * x; })
operations.RegisterOperator<2>([](int x, int y) {return x + y; })

但是它给了我一个函数风格的转换错误。据我所知,这是因为在一个函数中以两种不同的方式解释class T
我如何修改代码以使用argsCount的模板参数1或2调用该方法,以便知道class T是什么类型,以及必须将参数推送到哪个向量函数?
我尝试了不同的方法来解决这个问题。
第一种方法是在类中重载模板,如下所示:

template <size_t argsCount, class T>
void RegisterOperator(T fn) {
}

template<>
void RegisterOperator<1>(unFunPtr fn) {
    m_unaryOperations.push_back(fn);
}

template<>
void RegisterOperator<2>(binFunPtr fn) {
    m_binaryOperations.push_back(fn);
}

但是调试告诉我,它甚至不会进入重载函数内部,我写的例子上面的问题。
第二种方法是在类中重载模板,如下所示:

template<class T = unFunPtr>
void RegisterOperator<1>(T fn) {
    m_unaryOperations.push_back(fn);
}

template<class T = binFunPtr>
void RegisterOperator<2>(T fn) {
    m_binaryOperations.push_back(fn);
}

我以为默认模板只允许我在调用方法时在模板中定义argsCount,但它会导致很多错误。
希望你能帮忙。

xurqigkl

xurqigkl1#

首先,这里有一个错字:

std::vector<unFuncPtr> m_binaryOperations;
std::vector<binFuncPtr> m_unaryOperations;

它应该是:

std::vector<unFuncPtr> m_unaryOperations;
std::vector<binFuncPtr> m_binaryOperations;

第二,即使这样它也不会编译,因为对于“普通的”if,两个分支都需要是可编译的。如果你有C++17,你可以用if constexpr解决这个问题:

void RegisterOperator(T fn) {
  if constexpr (argsCount == 1) 
    m_unaryOperations.push_back(fn);

  if constexpr (argsCount == 2) 
    m_binaryOperations.push_back(fn);
}

现场演示:https://godbolt.org/z/bbqs7Knbd

相关问题