- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有以下代码。
#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/
我看到了这个问题 When is an object "out of scope"? 我看了sparc_spread 的回答,发现其中有一个问题。在他的回答的这一部分: Circle myFunc (
在程序中如下 #include struct A { A() { std::cout << "0"; } A( const A & ) { std::cout << "1"; }
在以下示例中,根据 this article 应用 NRVO(命名返回值优化): std::string f1() { std::string str; return str; //
#include using namespace std; int gc = 0; struct A { int id; A():id(gc++) { cout 1)。并且符合规范
class Date { private: int day,month,year; public: Date (int d,int m,int y) { day=d; month=m; year=y;
我们有一个广泛使用 out 参数的代码库,因为每个函数都可能因某些错误枚举而失败。这变得非常困惑,代码有时不可读。 我想消除这种模式并引入更现代的方法。 目标是转变: error_t fn(param
当我在 VS2010 中运行此代码时,不应用 NRVO。 #include class A { public: A() { printf( "I am in constructor\
我认为应该这样做,因为它对正确性很重要。但是,我很惊讶地看到 Clang 的输出。考虑以下代码: #include struct S { int i; S(int i) : i(i)
我希望了解 C++ 中 NRVO 的局限性。具有初始命名声明和单个返回的函数是否会针对 NRVO 进行优化并省略 T val,即使函数 myFunc() 具有抛出的可能性? T myFunc(bool
我有以下代码。 #include struct Box { Box() { std::cout << "constructed at " << this << '\n'; }
返回值优化机制的简短(可能过时且过于简单)总结如下 this : an implementation may create a hidden object in the caller's stack
我已经阅读了一些关于 move 函数的帖子(例如 http://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c
我需要调用一个函数为我返回一个对象。问题是对象有一个析构函数,它可以在函数输出被分配给另一个对象之前破坏数据。在我的程序中,我有一个 operator+,它将两个矩阵相加并返回两个矩阵的和: C=A+
我刚刚了解了 RVO(返回值优化)和 NRVO(命名返回值优化)。下面是两个例子 //Example of RVO Bar Foo() { return Bar(); } //Example
如果我编写一个在本地实例化对象然后按值返回的工厂方法,打算利用 NRVO(根据此处的一些答案:c++11 Return value optimization or move?),将指向本地对象的指针/
假设我有这样一个函数: using std::vector; vector build_vector(int n) { if (some_condition(n)) return {};
假设我们有以下代码: std::vector f() { std::vector y; ... return y; } std::vector x = ... x = f(); 似乎编译器
想象一下: S f(S a) { return a; } 为什么不允许别名a和返回值槽? S s = f(t); S s = t; // can't generally transform it
我一直在研究 NRVO 及其对不同编译器的支持,并遇到了奇怪的行为,这相当令人困惑。 示例代码: #include using namespace std; class X
自 1992 年以来我一直在使用 C++(并阅读了大量有关该语言的资料),因此我对这门语言有相当多的了解,但远非全部。我的问题是关于 C++11 命名返回值优化——有什么保证会执行?我倾向于发送非常量
我是一名优秀的程序员,十分优秀!