【发布时间】:2014-06-05 18:24:37
【问题描述】:
我有以下代码(简化):
#include <functional>
template <typename... Args> void Callback(std::function<void(Args...)> f){
// store f and call later
}
int main(){
Callback<int, float>([](int a, float b){
// do something
});
}
这样做的目的是获取一些额外的参数、发送数据包、处理响应并使用结果调用 lambda 问题是,它不需要 lambda。
# g++ -std=c++11 test.cpp
test.cpp: In function ‘int main()’:
test.cpp:8:3: error: no matching function for call to ‘Callback(main()::<lambda(int, float)>)’
test.cpp:8:3: note: candidate is:
test.cpp:2:34: note: template<class ... Args> void Callback(std::function<void(Args ...)>)
test.cpp:2:34: note: template argument deduction/substitution failed:
test.cpp:8:3: note: ‘main()::<lambda(int, float)>’ is not derived from ‘std::function<void(Args ...)>’
有没有什么方法可以让它工作而无需通过将 lambda 显式包装在 std::function 中的麻烦?
Callback(std::function<void(int, float)>([](int a, float b){
// do something
}));
即使省略回调模板参数(如此处所示),也可以完美运行。 不过仍然有“额外的”std::function。
为什么它不能自己计算出转换?它适用于非模板:
void B(std::function<void(int, float)> f){/* ... */};
int main(){
B([](int a, float b){
// do something
});
}
供参考,我正在使用
gcc 版本 4.7.2 (Debian 4.7.2-5)
【问题讨论】:
-
仅仅因为 lambda 可转换为
std::function并不意味着它是std::function。编译器应该如何从不相关的类型中找出std::function模板参数? -
@Praetorian:如果函数不包含模板参数(如上所述),它可以做到这一点,所以它应该(我认为)也适用于这种情况
-
模板参数推导 is 出错的地方,所以如果你把它排除在等式之外,它当然可以工作。阅读我在之前评论中链接到的答案。
-
@Praetorian:非常感谢! :)
标签: c++ templates c++11 lambda variadic-templates