【问题标题】:C++ template argument deduction with lambdas [duplicate]使用 lambda 进行 C++ 模板参数推导 [重复]
【发布时间】:2014-05-16 16:41:36
【问题描述】:

我有以下模板声明

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 () )

为什么模板参数推导失败?以及如何解决?

【问题讨论】:

  • 这应该可以工作,而且可能会更好... #define lmda_(...) (functionVA_ARGS)>)[&] (VA_ARGS) -> foo( lmda_(string s, bool b) { }); // 注意缺少的 () e:你需要在 va_args 前后加上 2 个下划线(它们在这里变成粗体格式的文本)
  • 机器人的 Lambda 平庸定律:如果您的设计关心 lambda,那就错了。 (也可以简单地表述为“lambdas are not special”)

标签: c++ templates c++11 lambda variadic-templates


【解决方案1】:

这是一个不可演绎的上下文。无法推导出模板参数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;
 };

所以即使tint(与100 的类型相同),模板参数也可以是doublefloat(或任何其他类型)。

【讨论】:

  • 也许你的意思是f({100});
  • @Constructor:已编辑以消除混乱!谢谢。
【解决方案2】:

标准库函数是一种可以保存任何对象的类型 可以使用调用运算符 () 进行调用,这意味着它在其他方面是 function 类型的对象是一个函数对象。

函数实例化期间 foo([] (string str){}); 编译器无法推断“函数”函数对象类的 T 类型 通过这种方式,我们明确指定了类型,从而可以更简洁地描述函数的依赖关系。 自动 func1 =[](字符串 str){}; 富(功能1); 要么 foo([] (string str){});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-07
    • 2013-06-30
    • 1970-01-01
    相关资源
    最近更新 更多