gpt4 book ai didi

c++ - 为什么复制省略对形式参数进行异常(exception)处理?

转载 作者:行者123 更新时间:2023-11-30 03:47:12 25 4
gpt4 key购买 nike

这是一个完整的程序:

#include <iostream>
using std::cout;
using std::endl;
using std::move;

int count {0}; // global for monitoring


class Triple {
public:
Triple() = default; // C++11 use default constructor despite other constructors being declared
Triple(Triple&&) = default;
Triple(const Triple& t) : // copy constructor
Triple(t.mX, t.mY, t.mZ) {
count++;
}

Triple(const int x, const int y, const int z) :
mX{ x }, mY{ y }, mZ{ z } {
}

const Triple& operator +=(const Triple& rhs) {
mX += rhs.mX;
mY += rhs.mY;
mZ += rhs.mZ;
return *this;
}

int x() const;
int y() const;
int z() const;

private:
int mX{ 0 }; // c++11 member initialization
int mY{ 0 };
int mZ{ 0 };
};


#if 0
inline Triple operator+(const Triple& lhs, const Triple& rhs) {
Triple left { lhs };
left += rhs;
return left;
}
#else
inline Triple operator+(Triple left, const Triple& rhs) {
left += rhs;
return left;
}
#endif

int main()
{
Triple a,b;

cout << "initial value of count is: " << count << endl;

auto result { a+b };

cout << "final value of count is: " << count << endl;
}

有趣的是复制构造函数有副作用,有两个版本的operator+ 可以考虑。

案例一

inline Triple operator+(const Triple& lhs, const Triple& rhs) {
Triple left { lhs };
left += rhs;
return left;
}

案例2

inline Triple operator+(Triple left, const Triple& rhs) {
left += rhs;
return left;
}

Visual Studio 2015 给出了相同的结果,打印出 1 的结果。但是 gcc 4.8.4 为案例 1 提供了 2

This summary of copy elision 声明“这不是函数参数”,这让我假设 VS 是错误的。对吗?

但是,为什么在此规则中对形式参数名称进行了特殊处理?为什么它与任何其他局部变量不完全一样?

(我并不是说优化器根据调用约定并根据调用者和调用者的单独编译来解决问题,只是为什么不允许.)

编辑:如果输出 1 是正确的,它如何符合省略规则?


注意※:我发现这段文字是从公开可用的§12.8第31段中复制的N3690 .

最佳答案

首先要明白RVO和NRVO是标准的编写者提供给编译器编写者的机会。给定的编译器可以自由地忽略 RVO 或 NRVO 的可能性,如果它不能让它工作,如果它不知道它是否可以让它工作,如果月亮是满的等等。

不过,在这种情况下,这很容易。 (N)RVO的根本实现方式,就是将返回值直接构造到返回值占用的内存中,甚至是将设置为该返回值的变量占用的内存中。

也就是说,(N)RVO 的潜在节省不仅来自于省略复制构造的能力,还来自于减少一般复制的能力。

但是当返回值的来源是函数参数时,就太晚了。 left 已经在内存中的某处,返回值必须去别的地方。缺少来自内联的一些蛮力假设规则,复制已经是给定的,因为已经构造了第二个对象。

关于c++ - 为什么复制省略对形式参数进行异常(exception)处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33790822/

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