作者:Kong倪 | 来源:互联网 | 2022-12-01 19:42
考虑这个简单的程序:
#include
void length(void){
std::cout<<"My length is void"<
该程序的输出是:
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
什么?
并且,因为我想要注册一个已经传递参数的函数,我搜索python lambda函数的C++类比,并找到类似的lambda函数,但它没有成功:**
#include
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类比,但这个问题的解决方案是什么?混淆的主要部分以粗体突出显示.
1> Nicol Bolas..:
这几乎看起来好像我们正在传递函数的地址,但是,从上面的程序中可以清楚地看出这不是一个地址
你有事情倒退了.这并不是glutDisplayFunc
在做奇怪的神奇事物; 它是std::cout
.
是的,函数名称将转换为函数指针.operator<<
iostreams和C++重载规则规则的重载组合最终导致<<
将函数视为布尔值(是的,真的).因此,你<就等同于做<.
如果你想要地址,你可以void*
在输出之前将函数指针强制转换为a :<(&length)
或者更简洁<<(void*)&length
(虽然从技术上讲,这只是C++有条件地支持,几乎每个真正的编译器都允许这样做).
最后,在C++中,lambdas不是函数; 他们是对象.您不能将对象传递给需要函数指针的对象.您可以将无捕获的lambda转换为函数指针,但是对于捕获值的函数,您不能这样做.