【发布时间】:2014-11-18 12:59:08
【问题描述】:
我有以下 C++11 示例,其中我有一个 call 函数,它使用可变参数模板来接受和调用泛型类方法:
#include <utility>
template <typename T, typename R, typename... Args>
R call(R (T::*fn)(Args...), T *t, Args&&... args) {
return ((*t).*fn)(std::forward<Args>(args)...);
}
class Calculator {
public:
int add(const int& a, const int& b) {
return a + b;
}
};
int main() {
Calculator *calculator = new Calculator();
int* a = new int(2);
int* b = new int(4);
// compiles
int res1 = calculator->add(*a, *b);
// does not compile!
int res2 = call<Calculator>(&Calculator::add,calculator, *a, *b);
return 0;
}
正如代码中所述,当函数接受const int 时,我无法传递int,而在方向方法调用中我可以。我收到以下编译错误:
error: no matching function for call to ‘call(int (Calculator::*)(const int&, const int&), Calculator*&, int&, int&)’
int res2 = call<Calculator>(&Calculator::add,calculator, *a, *b);
^
inconsistent parameter pack deduction with ‘const int&’ and ‘int&’
int res2 = call<Calculator>(&Calculator::add,calculator, *a, *b);
^
与常规执行相比,C++ 可变参数模板是否强制执行更严格的类型检查?我将 g++ 4.8.1 与 C++ 11 一起使用。
【问题讨论】:
-
也许你会更喜欢 Clang 的错误:注意:候选模板被忽略:推断参数“Args”的冲突类型(
vs. ) -
那么这是否意味着在使用可变参数模板时类型必须完全匹配?
-
这意味着你不能为同一个模板参数推导出不同的类型,因为编译器不知道你想要哪个。您总是可以跳过显式函数捕获,只使用一个可调用的对象参数:
template <typename F, typename T, typename... Args> auto call(F f, T *t, Args&&... args) { return (t->*f)(std::forward<Args>(args)...); } -
@chris:使用这种方法,我的调用方会是什么样子?我应该将什么作为
F类型的参数传递? -
只需删除显式模板参数。
标签: c++ templates variadic-templates