【问题标题】:How to define a lambda expression without both std::function and auto?如何在没有 std::function 和 auto 的情况下定义 lambda 表达式?
【发布时间】:2017-11-27 23:48:03
【问题描述】:

我已经阅读了“Effective Modern C++”的 item31 和 http://en.cppreference.com/w/cpp/language/lambda 的网页,想知道我是否可以通过其确定的类型而不是 std::function 的包装类型或 auto 的关键字来定义 lambda 和我怎样才能做到这一点。

例如,对于类型int

auto x_1 = 5; // type deduction
int x_2 = 5;  // defined by definite type
// both x_1, x_2 are int variables of value 5

现在,当问题出现在 lambda 时:

auto f_1_0 = []()->int{return 5;};
std::function<int(void)> f_1_1 = []()->int{return 5;};
SomeType f_2 = []()->int{return 5;}; // what's the SomeType here?

【问题讨论】:

  • Lambda 的类型名称无法表达。必须推断它们的类型。
  • 如果您想要一个具体的类型名称,请构建一个仿函数。 Lambda 是匿名的。
  • 技术上你可以,即通过重新实现std::function,但你的实际问题似乎是你是否可以发现 lambda 的类型名:你做不到。
  • 这取决于你想用 lambda 的名字做什么。如果你只是想看看编译器想出了什么,你可以使用print_T&lt;decltype(lambda)&gt;() where template &lt;typename T&gt; print_T() { std::cout &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; '\n'; }
  • @Henri "PRETTY_FUNCTION" 不是标准的东西。海合会,对吧? (我很佩服你让这个编辑器正确显示 PRETTY_FUNCTION_ 的能力。)

标签: c++ c++11 lambda


【解决方案1】:

每个 lambda 表达式都有自己独特的类型。

这里的表达式 f_1 和 f2 有不同的类型。

auto f_1 = []()->int {return 5; }; 
auto f_2 = []()->int {return 5; }; 

分配 f_2 = f_1 是非法的。

标准说这些类型是“未命名的”。在实践中,编译器可能为每个 lambda 组成一个新的、隐藏的类型名。 Visual C++17 给它们起了以下名字。

classmain::<lambda_7e9d7fb093569d78a8c871761cbb39d7>
classmain::<lambda_8f061a3967cd210147d6a4978ab6e125>

不是很有用的信息。

【讨论】:

    【解决方案2】:

    标准规定 lambda 的类型是未命名的,因此实现创建了一个实现定义的名称,它使用的名称类似于其他未命名的类、结构体 enumc 等。

    ISO C++:5.1.2 Lambda 表达式 [expr.prim.lambda]

    3 lambda 表达式的类型(也是闭包对象的类型)是唯一的,未命名非联合类类型——称为闭包类型——其属性如下所述.

    该标准还规定 lambda“表现得像一个函数”,因此您可以将它与 std::function 模板一起使用:

    [注意:闭包对象的行为类似于函数对象(20.9)。——结束注释]

    如果您真的想为自己命名,可以使用老式的functors,并使用lambdas 完成编译器为您完成的所有工作。

    【讨论】:

      【解决方案3】:

      在某些情况下你可以使用函数指针(使用mvcpp,0x17):

      auto usingAuto = []() {
          cout << "autoMagick" << endl;
      };
      void(*pureCpp)() = []() {
          cout << "pureCpp" << endl;
      };
      
      //pureCpp = usingAuto; //you can even assing function pointers from lambdas
      //usingAuto = pureCpp;  //error
      pureCpp();
      usingAuto();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-08-23
        • 2023-01-20
        • 2010-11-11
        • 1970-01-01
        • 2018-06-10
        • 1970-01-01
        • 2019-05-26
        • 1970-01-01
        相关资源
        最近更新 更多