c++ - 将 lambda 作为模板函数参数传递

标签 c++ c++11 templates lambda

为什么下面的代码不能编译(在 C++11 模式下)?

#include <vector>

template<typename From, typename To>
void qux(const std::vector<From>&, To (&)(const From&)) { }

struct T { };

void foo(const std::vector<T>& ts) {
    qux(ts, [](const T&) { return 42; });
}

错误信息是:

prog.cc:9:5: error: no matching function for call to 'qux'
    qux(ts, [](const T&) { return 42; });
    ^~~
prog.cc:4:6: note: candidate template ignored: could not match 'To (const From &)' against '(lambda at prog.cc:9:13)'
void qux(const std::vector<From>&, To (&)(const From&)) { }
     ^

但它并没有解释为什么它不能匹配参数。

如果我将 qux 设为非模板函数,则将 From 替换为 T 并将 To 替换为 int,它会编译。

最佳答案

lambda 函数不是普通函数。每个 lambda 都有自己的类型在任何情况下都不是 To (&)(const From&)
在您的情况下,非捕获 lambda 可以衰减为 To (*)(const From&):

qux(ts, +[](const T&) { return 42; });

如评论中所述,从 lambda 中取出它的最佳方法是:

#include <vector>

template<typename From, typename To>
void qux(const std::vector<From>&, To (&)(const From&)) { }

struct T { };

void foo(const std::vector<T>& ts) {
    qux(ts, *+[](const T&) { return 42; });
}

int main() {}

注意:我假设推断返回类型和参数类型对于真正的问题是强制性的。否则你可以很容易地将整个 lambda 推导出为一个通用的可调用对象并直接使用它,无需衰减任何东西。

关于c++ - 将 lambda 作为模板函数参数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41920890/

相关文章:

c++ - 为什么必须在线程销毁之前调用 join() 或 detach() ?

c++ - 没有参数列表时模板名称 ‘boost::asio::strand’ 的使用无效

c++ - 在 C++ 中执行具有任何类型和数量参数的任何函数的函数

c++ - 使用 C++ 概念检查其他类型的函数是否存在

c++ - C++ 中多线程的 join() 和 detach() 有什么不同?

c++ - 只从字符串、字符和 double 文件中读取 double

c++ - 扩展 CRTP 模板功能

c++ - 为什么 std::function 不是有效的模板参数,而函数指针是?

c++ - 使用 "--enable-vtable-verify"构建 Devtoolset 7 gcc

c++ - 用于创建字符串的 Variadic 模板函数