【问题标题】:How to declare the type of the closure that takes string, returns void?如何声明接受字符串的闭包类型,返回 void?
【发布时间】:2018-07-23 07:32:07
【问题描述】:

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

auto log_info =  [] (const std::string & str) { /* statements */ };

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

[] 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 的实际类型。你需要用 auto 或 template 推断它,但如果你有一个空的闭包,你的 lambda 将可以转换为函数指针
  • 看看std::function 看看它是否满足您的需求。
  • @SanderDeDycker OP 没有显示任何需要std::function exept 如果字段表示容器
  • @Tyker 我认为您的意思是说“空捕获子句”。这里似乎就是这种情况,因此您可以将其存储在 void (*variable_name)(const std::string &) 类型的函数指针中
  • 嗯...如果它是无捕获的,为什么不使用常规功能呢?

标签: c++ closures c++14


【解决方案1】:

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

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

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

当您将状态放入捕获中时,上述 sn-p 将失败。然后,您可能想要切换到类模板:

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

   Fct closure;
};

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

B b{[](const std::string&){}};

【讨论】:

  • 出于好奇,您打算如何将课程设为模板?如果类正在初始化成员本身,则用户将无法指定类型,除非他们使用类型擦除的东西,此时您可以直接执行此操作。如果 lambda 有捕获,我能做的最好的就是让它成为一个具有可拼写类型的实际类。
  • @chris 我没有计划任何事情,但是参考模板解决方案通常被认为是一种好的做法:P 当然,您是对的。与在实例初始化中硬编码相比,通过构造函数注入 lamdba 在任何情况下都是更好的用例。
【解决方案2】:

std::function&lt;void(const std:string)&gt; 是你要找的吗?

【讨论】:

    【解决方案3】:
      std::function<void(const std::string&)> log_info = [](const std::string& str) {
        /* Statements */
      };
    

    感谢您提供查看 std::function 的提示。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-24
    • 2021-06-29
    • 2020-11-01
    • 1970-01-01
    • 2017-06-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多