具有宽松类型要求的 C++17 lambda 捕获

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

我有以下代码,它可以用 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
}

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

最佳答案

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

在 C++14 中,这个:

auto barlam = [bar]{};

仍然需要 move-construction 是有效的(即使你不想要移动并且移动很可能无论如何都会被省略)。但是那个 lambda 不是可移动构造的,因为 Bar 不是可移动构造的。 Foo 是可移动构造的,因此 foolam 工作正常。

这个的非 lambda 版本是:

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

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

auto bar = Bar{};

完全等同于:

Bar bar{};

这同样适用于 lambda。

关于具有宽松类型要求的 C++17 lambda 捕获,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55245800/

相关文章:

C++ 编译时检查微 Controller 引脚是否已从其他源文件初始化

c++ - 如何在 C++ 中使用 std::vector 作为 std::unordered_map 的键类型?

c++ - memcmp 链接器错误 Visual Studio 2015

c++ - 错误 LNK2019 : unresolved external symbol _main referenced in function ___tmainCRTStartup

amazon-web-services - AWS Lambda 任务在 6.00 秒后超时

c++ - 具有段错误的函数模板

c++ - Unix - 防止内存消耗失控导致 PC 崩溃?

python数据帧: return column name in apply lambda

python - 无法将信息传递给回调函数

c++ - 使用原子锁定免费的单个生产者多个消费者数据结构