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
并非没有一些严重的开销。你应该记住这一点。性能问题: