如何声明接受字符串、返回 void 的闭包类型?

h22*_*h22 1 c++ closures c++14

我有一个闭包作为全局变量,它必须只接受一个字符串(并记录它):

\n\n
auto log_info =  [] (const std::string & str) { /* statements */ };\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在我想创建对象的一个​​字段,现在编译器要求我指定实际类型。它属于哪一种类型?以下是我尝试过但没有取得多大成功的声明:

\n\n
[] log_info =  [] (const std::string & str) \n[] (const std::string & str) log_info =  [] (const std::string & str)\n(const std::string & str) log_info =  [] (const std::string & str)\n
Run Code Online (Sandbox Code Playgroud)\n\n

我还尝试从编译器错误消息中猜测类型,但似乎对这个秘密很坚定:

\n\n
int log_info =  [] (const std::string & str)\n
Run Code Online (Sandbox Code Playgroud)\n\n

: 从 \xe2\x80\x98\xe2\x80\x99 到 \xe2\x80\x98int\xe2\x80\x99 的用户定义转换无效

\n\n

它是对采用 const std::& 字符串并返回 void 的闭包的引用。如何声明这样的类型,或者我需要不同的方法?

\n

lub*_*bgr 5

因为您显示的 lambda 没有状态,所以它可以隐式转换为函数指针,如下所示:

struct A {
   /* Your member variable declaration: */
   void (*closure) (const std::string&);

   /* Initialize it with a lamdba. */
   A() : closure([](const std::string&){}) {}
};
Run Code Online (Sandbox Code Playgroud)

当您将状态放入捕获中时,上面的代码片段将失败。然后,您可能想切换到类模板:

template <class Fct> struct B {
   B(Fct&& f) : closure(std::forward<Fct>(f)) {}

   Fct closure;
};
Run Code Online (Sandbox Code Playgroud)

这里,lamdba 必须在实例化时传递,并且对于编译器推导的类型,需要 C++17:

B b{[](const std::string&){}};
Run Code Online (Sandbox Code Playgroud)