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

C++ 如何声明接受字符串并返回void的闭包类型?,c++,closures,c++14,C++,Closures,C++14,我有一个作为全局变量的闭包,它必须只接受一个字符串(并记录它): 现在我想为对象创建一个字段,现在编译器要求我指定实际的类型。是哪种类型的?以下是我尝试过但没有成功的声明: [] log_info = [] (const std::string & str) [] (const std::string & str) log_info = [] (const std::string & str) (const std::string & str) log_in

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

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

[] log_info =  [] (const std::string & str) 
[] (const std::string & str) log_info =  [] (const std::string & str)
(const std::string & str) log_info =  [] (const std::string & str)
我还试图从编译器错误消息中猜出类型,但似乎坚定了秘密:

int log_info =  [] (const std::string & str)
:从“”到“int”的用户定义转换无效


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

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

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

   /* Initialize it with a lamdba. */
   A() : closure([](const std::string&){}) {}
};
当您在捕获中放入状态时,上述代码段将失败。然后,您可能希望切换到类模板:

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

   Fct closure;
};

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

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

   /* Initialize it with a lamdba. */
   A() : closure([](const std::string&){}) {}
};
当您在捕获中放入状态时,上述代码段将失败。然后,您可能希望切换到类模板:

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

   Fct closure;
};
std::function
是您要找的吗?

std::function
是您要找的吗?

std::function log\u info=[](常量std::string&str){
  std::function<void(const std::string&)> log_info = [](const std::string& str) {
    /* Statements */
  };
/*声明*/ };
感谢您提供查看std::function的提示。

std::function log\u info=[](const std::string&str){
/*声明*/
};

感谢您给我们一个关于std::function的提示。

lambda的实际类型尚不清楚。您需要使用auto或template进行推断,但如果您有一个空闭包,则lambda将转换为函数点。请查看它是否满足您的需要。@Sanderedycker OP没有显示任何需要
std::function
exept if field means的内容container@Tyker我想你的意思是说“空捕获条款”。这里似乎就是这种情况,因此您可以将其存储在类型为
void(*variable_name)(const std::string&)的函数指针中。
um。。。如果捕获较少,为什么不使用常规函数呢?lambda的实际类型未知。您需要使用auto或template进行推断,但如果您有一个空闭包,则lambda将转换为函数点。请查看它是否满足您的需要。@Sanderedycker OP没有显示任何需要
std::function
exept if field means的内容container@Tyker我想你的意思是说“空捕获条款”。这里似乎就是这种情况,因此您可以将其存储在类型为
void(*variable_name)(const std::string&)的函数指针中。
um。。。如果捕获较少,为什么不使用一个常规函数呢?出于好奇,您计划如何使类成为模板?如果类正在初始化成员本身,用户将无法指定类型,除非他们使用类型擦除的内容,此时您可以直接这样做。如果lambda有捕获,我所能做的最好的事情就是使它成为一个具有可拼写类型的实际类。@chris我没有计划任何事情,但引用模板解决方案通常被认为是一种良好的做法:P当然,你是对的。在任何情况下,通过构造函数注入lamdba都比在实例初始化中硬编码更好?如果类正在初始化成员本身,用户将无法指定类型,除非他们使用类型擦除的内容,此时您可以直接这样做。如果lambda有捕获,我所能做的最好的事情就是使它成为一个具有可拼写类型的实际类。@chris我没有计划任何事情,但引用模板解决方案通常被认为是一种良好的做法:P当然,你是对的。在任何情况下,通过构造函数注入lamdba都比在实例初始化中硬编码要好。
std::function
并非没有一些严重的开销。你应该记住这一点。性能问题:
std::function
并非没有一些严重的开销。你应该记住这一点。性能问题: