【发布时间】:2018-10-19 13:15:53
【问题描述】:
考虑这个简单的程序:
#include <iostream>
void length(void){
std::cout<<"My length is void"<<std::endl;
}
void width(void){
std::cout<<"My width is void"<<std::endl;
}
int main(void){
std::cout<<"The program length is: "<<length<<std::endl;
std::cout<<"The program width is: "<<width<<std::endl;
}
这个程序的输出是:
The program length is: 1
The program width is: 1
程序打印出来的数字是什么,基本上没有太多的C++知识,这对我来说看起来更像pythonic语法,看起来好像应该打印函数地址。我这么说是因为,这个问题最初是在练习一些非常基本的openGL程序时出现的,
回调在 GLUT 中注册,如下所示:
void line(void){
//some code for line program ...
}
int main(int argc, char** argv){
//some more code;
glutDisplayFunc(line);
glutMainLoop();
}
看起来好像我们在传递函数的地址,但是,从上面的程序很明显这不是地址,并且指向函数的语法有点不同,如果是这样,如何这个函数是否注册回调?我们要传递给glutDisplayFunc的是什么?
而且,由于我**想注册一个已传递参数的函数,所以我在 C++ 类比中搜索了 python lambda 函数,并找到了类似的 lambda 函数,但没有成功:**
#include <iostream>
void line(int a, int b){
//some code that does some plotting in the display window
}
int main(int argc, char** argv){
auto callback = [](void)->void{
line(a,b);
};
glutDisplayFunc(callback);
glutMainLoop();
}
这完全失败了,显示的错误是:
no suitable conversion function from "lambda []void ()->void" to "void (*)()" exists
这是使用我的 python 类比,但是这个问题的解决方案是什么?混淆的主要部分以粗体突出显示。
【问题讨论】:
-
在 C++ 中,非成员函数自然会衰减为指向自身的指针。在这种情况下,
line等于&line。 -
您问题的前半部分已回答here。我建议从你的问题中删除它,然后问为什么你不能通过 lambda。
-
Lambda 具有编译器生成的类型,这些类型不同于所有其他类型 - 特别是与(指向)函数的不同类型。您的函数需要一个指向不接受参数并返回
void(即void (*)())的函数的指针。没有 lambda 可以有这种类型。 -
@Peter 但是,非捕获 lambdas 将隐式转换运算符获取到其调用类型的函数指针。
[](){}可以隐式转换为void(*)()