lambda不是函数指针! lambda是编译器生成的类的实例!
int main() {
auto lambda = [](int a) { return a; };
func ptr = +lambda; // this would work
return 0;
}
可悲的是,operator+
甚至不会在你的情况下工作,因为它具有:
然而,非捕获拉姆达可以使用它的operator+
下面是一个例子转换为函数指针没有被声明为constexpr,所以你不能在模板参数中使用它。
对你的情况的修复将是使用免费功能...直到N4487不被接受,你不能指望将lambda作为模板参数。
另一个解决将是创造,而不是一个拉姆达自己的仿函数:
struct LambdaType {
constexpr LambdaType() = default;
int operator()(int a) {
return run(a);
}
// this is a non-capturing lambda, the operator can be
// in a static function
static int run(int a) {
return a;
}
};
int main() {
LambdaType lambda;
function<&LambdaType::run>(1); // ---> this is working
return 0;
}
该解决方案是不是很吸引人,但如果LambdaType
是隐藏在一个CPP文件时,它可能是有用的。
如果你的目标仅仅是编译器能够内联的代码,您可以使用模板来绕过拉姆达:
#include <iostream>
template <typename T>
int function(T foo, int a) {
return foo(a);
}
int main() {
int a;
std::cin >> a;
int b = function([](int a) { return a; }, a);
return b;
}
由于编译器知道的T
每个instanciation类型,好编译器应该能够优化出lambda。
铿锵,第三个选项提供了以下组件:
main: # @main
pushq %rax
leaq 4(%rsp), %rsi
movl std::cin, %edi
callq std::basic_istream<char, std::char_traits<char> >::operator>>(int&)
movl 4(%rsp), %eax # this is the call to the function
addq $8, %rsp
retq
pushq %rax
movl std::__ioinit, %edi
callq std::ios_base::Init::Init()
movl std::ios_base::Init::~Init(), %edi
movl std::__ioinit, %esi
movl $__dso_handle, %edx
popq %rax
jmp __cxa_atexit # TAILCALL
我以前-std=c++14 -Ofast -march=native
作为标志。
'function(1);'不是'ok'。模板需要一个类型或一个整数常量作为参数。 “测试”既不是。并且都不是'lambda'。 –
DeiDei
这是确定的,检查这个答案http://stackoverflow.com/questions/1174169/function-passed-as-template-argument/2156899#2156899,你也可以尝试它 – gsf
lambda已经是std ::函数类型。你在做什么看起来像函数)>(1)这是无效的(因为1是一个int不是函数)。 –
Striker