c++ - 通过参数传递 lambda(无函数类型模板)
问题描述
我想在此处不使用函数模板,而是使用std::function
或类型化函数指针来传递 lambda。
#include <iostream>
#include <list>
#include <functional>
template<typename T>
std::list<T> mapll(std::function<T(T)> f, std::list<T> l) {
for(auto it = l.begin(); it != l.end(); ++it) {
*it = f(*it);
}
}
int main() {
// Make it
std::list<int> l = std::list<int> {1,2,3};
// Map it
mapll([](int n) { return n * 2; }, l);
// Print it
std::cout << "{";
for (auto it = l.begin(); it != l.end(); ++it) {
if (it == l.begin())
std::cout << "," << *it;
std::cout << *it;
}
}
但我没有成功调用mapll
. 错误是:
clang++ -g -DNDEBUG -std=c++17 -Wno-switch-bool -lc main.cpp -o main
main.cpp:51:2: error: no matching function for call to 'mapll'
mapll([](int n) { return n * 2; }, l);
^~~~~ main.cpp:42:14: note: candidate template ignored: could not match
'function<type-parameter-0-0 (type-parameter-0-0)>' against
'(lambda at main.cpp:51:8)' std::list<T> mapll(std::function<T(T)> f, std::list<T> l) {
解决方案
没有推导出std::function
参数,因为 lamdbas 是可转换为std::function
对象的不同类型,但这种转换不是类型推导的一部分。以下是它应该如何工作std::function
:
template<typename T>
void mapll(std::function<T(T)> f, std::list<T>& l) {
for(auto it = l.begin(); it != l.end(); ++it) {
*it = f(*it);
}
}
/* ... */
mapll(std::function<int(int)>{[](int n) { return n * 2; }}, l);
正如您提到的使用函数指针的可能解决方案,这将是:
template<typename T>
void mapll(int (*f)(int), std::list<T>& l) {
/* Function body identical to the one above. */
}
/* ... */
/* The stateless lambda converts to the function pointer: */
mapll([](int n) { return n * 2; }, l);
不幸的是,上面的函数指针在int
s 上运行,这在std::list<T>
. 使用通用函数指针,mapll
函数签名更改为
template<typename T>
void mapll(T (*f)(T), std::list<T>& l)
但同样,int
参数/返回类型的 lamdba 并没有推导出来匹配这个函数指针。你必须明确地转换它:
mapll(static_cast<int(*)(int)>([](int n) { return n * 2; }), l);
请注意,正如评论中指出的那样,您还应该考虑std::transform
. mapll
而且我已经更改了函数模板的返回值(为 void)和第二个参数类型(为左值引用) 。
推荐阅读
- angular5 - 如何在 p 列 PrimeNG 表中显示组?
- javascript - 在PHP中的单个对象数组中获取多个JSON对象数组
- mysql - 无法从mysql中的三个表中获取不匹配的行
- react-native - 反应原生样式组件
- sockets - 关闭从 TCP 连接读取的 goroutine 而不关闭连接
- angular - 从外部 js 文件更改离子输入的值
- comments - 通过 RapidXML 在 XML 文件中获取注释
- matlab - MATLAB:大文本文件到矩阵的转换
- c - 为什么不能将静态结构指针初始化为变量的地址
- java - Eclipse 氧气 4.7.3a 上的 Java swing?