gpt4 book ai didi

c++ - NRVO 什么时候开始?需要满足哪些要求?

转载 作者:行者123 更新时间:2023-12-04 11:22:55 25 4
gpt4 key购买 nike

我有以下代码。

#include <iostream>    
struct Box {
Box() { std::cout << "constructed at " << this << '\n'; }
Box(Box const&) { puts("copy"); }
Box(Box &&) = delete;
~Box() { std::cout << "destructed at " << this << '\n'; }
};

auto f() {
Box v;
return v; // is it eligible for NVRO?
}

int main() {
auto v = f();
}
上面的代码产生错误。 call to deleted constructor/function in both gcc and clang但是,如果我更改代码以返回纯右值,则代码有效。
auto f() {
Box v;
return Box(); // is it because of copy elision?
}

为什么会这样?是因为删除移动构造函数吗?
如果我将复制和移动构造函数都更改为显式,它也会产生错误吗?
如果标记为已删除,为什么不能简单地使用定义的复制构造函数
编辑:
      compiled with -std=c++20 in both gcc and clang, error.
compiled with -std=c++17 gcc, compiles.
compiled with -std=c++17 clang, error.
编辑2:
      clang version: 12.0.0
gcc version: 11.1

最佳答案

该程序中有两种不同的潜在错误。auto v = f();是 C++14 及以下的错误,因为该操作在逻辑上是移动构造,而不是 C++17 及更高版本的错误,因为它是临时而非移动构造的具体化。这是 C++17 的保证复制省略功能,与 NRVO 不同。return v;在所有版本的 C++ 中都是一个错误,因为它在逻辑上是一个移动构造,并且构造函数需要存在且可访问。 NRVO 大部分时间都会优化构造函数,但 NRVO 不是强制性的,它只是允许的,因此它不能使原本无效的程序有效。但是,gcc 不会通过 std=c++17 捕获此错误和更低。相反,它回退到复制构造函数。这似乎是一个 gcc 错误。
C++17 不强制要求 NRVO。它在 return 中强制要求复制省略当操作数是纯右值时的语句,因此在这种情况下不需要存在复制/移动构造函数。这就是为什么return Box();作品。

关于c++ - NRVO 什么时候开始?需要满足哪些要求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68034285/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com