在C++中实现回调函数时,我是否还应该使用C风格的函数指针:
void (*callbackFunc)(int);
Run Code Online (Sandbox Code Playgroud)
或者我应该使用std :: function:
std::function< void(int) > callbackFunc;
Run Code Online (Sandbox Code Playgroud) 我正在玩C++ lambdas以及它们对函数指针的隐式转换.我的开始示例是将它们用作ftw函数的回调.这按预期工作.
#include <ftw.h>
#include <iostream>
using namespace std;
int main()
{
auto callback = [](const char *fpath, const struct stat *sb,
int typeflag) -> int {
cout << fpath << endl;
return 0;
};
int ret = ftw("/etc", callback, 1);
return ret;
}
Run Code Online (Sandbox Code Playgroud)
修改后使用捕获:
int main()
{
vector<string> entries;
auto callback = [&](const char *fpath, const struct stat *sb,
int typeflag) -> int {
entries.push_back(fpath);
return 0;
};
int ret = ftw("/etc", callback, 1);
for (auto entry : entries …Run Code Online (Sandbox Code Playgroud) 什么是std :: function <>和标准函数指针之间的区别?
那是:
typedef std::function<int(int)> FUNCTION;
typedef int (*fn)(int);
Run Code Online (Sandbox Code Playgroud)
它们实际上是一回事吗?
我试图弄清楚如何在自身中获取lambda函数的地址。这是一个示例代码:
[]() {
std::cout << "Address of this lambda function is => " << ????
}();
Run Code Online (Sandbox Code Playgroud)
我知道我可以在变量中捕获lambda并打印地址,但是我想在执行此匿名函数时就地执行此操作。
有没有更简单的方法?
#include <iostream>
void IsTrue(const bool value) {
if (value) {
std::cout << "value is True!\n";
}
}
int main()
{
IsTrue([]() { ; /* some lambda */ });
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
value is True!
Run Code Online (Sandbox Code Playgroud)
为什么lambda会评估trueGCC和Clang?MSVC无法构建此(无法将lambda转换为bool).
这是编译器错误吗?或者标准的哪一段允许这个?
我正在尝试在使用标准函数指针+上下文范例的C-API中注册回调.这是api的样子:
void register_callback(void(*callback)(void *), void * context);
Run Code Online (Sandbox Code Playgroud)
我真正想做的是能够注册一个C++ lambda作为回调.另外,我希望lambda是一个捕获变量的(即无法转换为直的无状态std::function)
我需要写什么样的适配器代码才能将lambda注册为回调?
我想使用lambda作为C++函数的参数,但我不知道在函数声明中指定哪种类型.我想做的是:
void myFunction(WhatToPutHere lambda){
//some things
}
Run Code Online (Sandbox Code Playgroud)
我曾尝试void myFunction(auto lambda)和void myFunction(void lambda),但没有这些代码的编译.如果重要,lambda不返回任何东西.
如何在lambin C++函数中使用lambda作为参数?
我希望能够根据从文件中读取的数据调用函数.因此,对于每种项目类型,我想调用所需的读者方法.我编写了这段代码,但它没有编译我想在地图中添加函数指针的地方.怎么了?
#include <vector>
#include <map>
#include <iostream>
class reader
{
std::map< std::string, void(*)()> functionCallMap; // function pointer
void readA(){ std::cout << "reading A\n";};
void readB(){ std::cout << "reading B\n";};;
public:
reader()
{
*functionCallMap["A"] = &reader::readA;*
*functionCallMap["B"] = &reader::readB;*
}
void read()
{
auto (*f) = functionCallMap["A"];
(*f)();
}
};
Run Code Online (Sandbox Code Playgroud)
我在Constructor填写地图.
通常,没有捕获的C++ lambda 应该可以转换为c风格的函数指针.不知何故,使用它进行转换std::function::target不起作用(即返回nullptr),target_type即使它看起来是相同的,也与签名类型不匹配.
在VC13和GCC 5.3/5.2.0/4.8上测试
最小的测试示例:
#include <functional>
#include <iostream>
void Maybe() {
}
void callMe(std::function<void()> callback) {
typedef void (*ftype)();
std::cout << (callback.target_type() == typeid(ftype)) << std::endl;
std::cout << callback.target<ftype>() << std::endl;
}
int main() {
callMe([] () {});
callMe(Maybe);
}
Run Code Online (Sandbox Code Playgroud)
预期产量将是
1
<address>
1
<address>
Run Code Online (Sandbox Code Playgroud)
实际产出
0
0
1
<address>
Run Code Online (Sandbox Code Playgroud)
问题是:为什么lambda的签名与传递的函数不同?
众所周知,lambda函数是引擎盖下的函子.
在这段视频中(@约45:43)Bjarne说:
我提到lambda会转换为函数对象,如果方便的话会转换为函数
我可以看到这是一个编译器优化(即它不会改变lambda作为未命名的仿函数的感知,这意味着例如lambda仍然不会重载)但是有没有规定何时适用?
我理解术语翻译的方式(这就是我所要求的)与转换无关(我不会问lambdas是否可以转换为函数ptr等).通过翻译我的意思是"将lambda表达式编译成函数而不是函数对象".
如cppreference中所述: lambda表达式构造一个未命名的prvalue临时对象,该对象具有唯一的非命名非联合非聚合类型,称为闭包类型.
问题是:这个对象可以被省略并且具有简单的功能吗?如果是,那么何时以及如何?
注意:我想象一个这样的规则是"不捕获任何东西",但我找不到任何可靠的来源来证实它