vso*_*tco 8 c++ templates variadic-templates c++11
我有以下代码:
#include <iostream>
#include <functional>
template<typename Return, typename... Params>
void func(std::function<Return(Params... )> x) {}
void f(double) {}
int main() {
//func<void, double>(f); // compile error here in the variadic case
func(std::function<void(double)>(f));
}
Run Code Online (Sandbox Code Playgroud)
我有两个问题:
我不明白为什么这行func<void, double>(f);会给我一个编译错误
/Users/vlad/minimal.cpp:10:5: error: no matching function for call to 'func'
func<void, double>(f); // compile error here in the variadic case
^~~~~~~~~~~~~~~~~~
/Users/vlad/minimal.cpp:5:6: note: candidate template ignored: could not match 'function<void (double, type-parameter-0-1...)>' against 'void (*)(double)'
void func(std::function<Return(Params... )> x) {}
^
1 error generated.
Run Code Online (Sandbox Code Playgroud)
而如果我将参数f转换为std::function(如在非注释行中)它可以工作.
2.最令人费解的问题是,如果我使用非变量版本func(即只是替换typename...为typename实际上func需要一个std::function<Return(Params)>as参数),那么注释行将main按照需要工作.有什么想法吗?
Jon*_*ely 11
我不明白为什么这行
func<void, double>(f);会给我一个编译错误
编译器不知道你想Params成为准确 double,它认为也许你希望它演绎一包有更多的元素,比如double, int, void*, char或double, double, double或类型的其他一些包,它不知道如何推断,从参数f.
从理论上说可能有其他专长的std::function可能是constructible从f并让编译器来推断一个以上类型的包Params(它无法知道这是不是没有真正的实例每一个可能的专业化std::function和测试它们,这是不可行的.
而如果我将参数
f转换为std::function(如在非注释行中)它可以工作.
因为现在编译器能够Params正确推导出来.
最令人费解的问题是,如果我使用
func[...] 的非变量版本,那么主要的注释行将按照需要使用.有什么想法吗?
因为现在编译器知道它Params是单个类型,而不是一个零或更多类型的包,所以当你说它func<void, double>知道Params是double,而不是double, int, void*, char或其他一些参数包时.
编辑回答您的评论,请考虑以下事项:
template<typename T, typename U, typename V>
int func(T t, U u, V v)
{ return 0; }
int i = func<int, char>(1, '2', "three");
Run Code Online (Sandbox Code Playgroud)
我只给出了两个参数的显式模板参数,因此仍然必须推导出第三个参数.
当您拥有可变参数模板时,可能还有许多其他参数需要推导出来.