我需要一些关于模板的帮助。我有这样的代码,它是一个类,包含两个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
,但它会导致很多错误。
希望你能帮忙。
1条答案
按热度按时间xurqigkl1#
首先,这里有一个错字:
它应该是:
第二,即使这样它也不会编译,因为对于“普通的”
if
,两个分支都需要是可编译的。如果你有C++17,你可以用if constexpr
解决这个问题:现场演示:https://godbolt.org/z/bbqs7Knbd