【问题标题】:C++17 lambda captures with relaxed type requirements具有宽松类型要求的 C++17 lambda 捕获
【发布时间】:2019-03-19 16:29:40
【问题描述】:

我有以下代码,它可以使用 C++17 编译器编译,但不能使用 C++14。我想知道发生了什么变化,允许编译以下代码:

struct Foo{
  Foo()=default;
  Foo(const Foo&)=default;// copy by const ref 
};

struct Bar{
  Bar()=default;  
  Bar(Bar&)=default; //copy by non const
};

int main()
{
  Foo foo;
  Bar bar;
  Bar barcpy = bar;
  auto foolam = [foo]{};
  auto barlam = [bar]{}; //compiles only with C++17
}

是否有任何关于编译此代码的确切建议,或者它是通过一些其他功能的方式?

【问题讨论】:

    标签: c++ lambda c++14 c++17


    【解决方案1】:

    Guaranteed Copy Elision(与wording)。这里的 lambda 实际上是一条红鲱鱼。

    在 C++14 中,这个:

    auto barlam = [bar]{};
    

    仍然需要移动构造是有效的(即使你不想要移动并且移动很可能被忽略)。但是那个 lambda 不是可移动构造的,因为 Bar 不是可移动构造的。 Foo 可移动构造的,所以 foolam 工作正常。

    这个的非 lambda 版本是:

    auto bar = Bar{}; // error in C++14
    auto foo = Foo{}; // ok
    

    在 C++17 中,这不是移动构造——我们只是直接初始化目标对象。从某种意义上说,我们正在忽略这一举动。在不同的意义上,实际上根本没有语言规则的移动。所以这个:

    auto bar = Bar{};
    

    完全等同于:

    Bar bar{};
    

    同样适用于 lambda。

    【讨论】:

    • 太棒了。谢谢!我知道有保证的副本省略,但我永远不会猜到这是原因,为什么会这样。
    猜你喜欢
    • 2017-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    • 1970-01-01
    相关资源
    最近更新 更多