C++ 将指向lambda函数的指针指定给指向另一个lambda函数的指针
我试图将一个指向lambda函数的指针分配给另一个lambda函数的指针。代码本身就说明了这一点:C++ 将指向lambda函数的指针指定给指向另一个lambda函数的指针,c++,pointers,c++11,lambda,C++,Pointers,C++11,Lambda,我试图将一个指向lambda函数的指针分配给另一个lambda函数的指针。代码本身就说明了这一点: #include <iostream> int main(int argc, char *argv[]) { auto l1 = []() { std::cout << "Lambda 1!" << std::endl; }; auto l2 = [] { std::cout << "Lambda 2!" << std
#include <iostream>
int main(int argc, char *argv[]) {
auto l1 = []() { std::cout << "Lambda 1!" << std::endl; };
auto l2 = [] { std::cout << "Lambda 2!" << std::endl; };
auto l1p = &l1;
l1p = &l2; // Why can't I do this assignment?
return 0;
}
#包括
int main(int argc,char*argv[]){
自动l1=[](){std::cout[expr.prim.lambda]/2:
lambda表达式的类型(也是
闭包对象)是唯一的、未命名的非联合类类型,称为
闭包类型-其属性如下所述
也就是说,两种闭包类型始终是完全不同和不相关的。但是,在您的示例中,由于两种lambda都没有捕获任何内容,因此可以将它们转换为类型为void(*)(
)的函数指针
也许你是有意的
void (*l1p)() = l1;
l1p = l2;
让我们去掉lambda函数提供的语法糖分:
struct lambda1 {
void operator () {
std::cout << "Lambda 1!" << std::endl;
}
};
struct lambda2 {
void operator () {
std::cout << "Lambda 2!" << std::endl;
}
};
int main(int argc, char *argv[]) {
auto l1 = Lambda1{};
auto l2 = Lambda2{};
auto l1p = &l1; // l1p is a Lambda1 *
l1p = &l2; // &l2 is a Lambda2 *
return 0;
}
struct lambda1{
void运算符(){
标准::cout{
// ...
};
/*
[整数]
(布尔旗){
如果(flag)不能作为一个加法,则可以使用运算符+
,使类型推断和lambda函数指针衰减:
auto l1p = +l1; // l1p is void (*)()
// ^
l1p = l2;
我明白了这个例子。但是问题是,C++(lam+)lambdas真的是(C++ 1)闭包的语法糖吗?据我所知,是()它们只是糖。C++(11)中我更喜欢使用std::function l1f=l1;l1f=l2;
,因为它更易于阅读。@SimonKraemer请不要这样做。std::function
的开销不值得稍微的语法改进。只需使用typedef
@Quentin我刚刚检查了编译器的输出。我对巨大的开销感到非常惊讶。谢谢谢谢你指出它。@SimonKraemerstd::function
的名字真的不够吓人。它不是“函数”,它是一个类型擦除的functionoid容器。我听说过一些疯狂的编译器试图在某些情况下通过它进行优化,但你可能不想依赖它;)@SimonKraemer它是一个类型安全的包装器……适用于任何可调用的。一个函数指针、一个带有运算符()的手写类、一个lambda等。这可能需要堆分配(存储状态)(某些实现有一个小对象优化),但确实涉及vtable或用于分派的等效项。调用开销类似于()
处的虚拟函数调用,它略多于函数指针调用,但更难内联。
auto l1p = +l1; // l1p is void (*)()
// ^
l1p = l2;