我有以下模板声明
template<typename T>
void foo(function<void(T)> f){
// ...
};
但是当我这样称呼它时
foo([](string s){ });
// visual studio 13 error message =>
// Error: void foo(std::function<void(_Type)>)' :
//could not deduce template argument for 'std::function<void(_Type)>'
//from 'main::<lambda_58b8897709e10f89bb5d042645824f66>
模板参数推断失败。 为什么?如何解决?
我对可变参数模板有同样的问题
template<typename ... Tn>
void foo(function<void(Tn ...)> f){
// ...
};
int main() {
foo<string,bool>([](string s,bool b){ }); // Works
foo([](string s,bool b){ }); // Fails
}
但是如果我明确地施放了lambda它就可以了(!)
foo((function<void(string,bool)>) [](string s,bool b){ }); // Works
// Or even a simpler syntax with a macro
#define lmda_(a) (function<void a>)[&] a
foo( lmda_((string s, bool b)) { }); // Works (note the extra () )
为什么模板参数推断失败?以及如何解决它?
答案 0 :(得分:4)
这是一个不可推断的背景。无法推断出模板参数T
。
这是一个最简单的例子。给出:
template<typename T>
struct X
{
X(T t) : data(t) {}
T data;
};
template<typename T>
void f(X<T> param);
现在你正在做这样的事情:
f(100);
认为T
将推断为int
。没有。它不会推断到int
。因为T
可能有多种可能性。例如,可能有专业化:
template<>
struct X<double>
{
X(int t) : data(t) {}
int data;
};
template<>
struct X<float> //another specialization
{
X(int t) : data(t) {}
int data;
};
即使t
是int
(与100
的类型相同),模板参数可以是double
或float
(或任何其他类型)。
答案 1 :(得分:0)
标准库函数是一种可以容纳任何对象的类型 可以使用调用operator()调用,这意味着它以其他方式 函数类型的对象是一个函数对象。
在函数实例化期间foo([](string str){}); 编译器无法推断出&#34;函数&#34;的类型。函数对象类 通过这种方式,我们明确指定了导致描述函数依赖关系的更简洁方式的类型。 auto func1 = [](string str){}; FOO(func1的); 要么 foo([](string str){});