提问人:pauk 提问时间:10/29/2023 更新时间:10/29/2023 访问量:64
转换为右值引用可防止复制省略
Cast to rvalue reference prevents copy elision
问:
我阅读了更多相关文章,但没有一个答案能澄清我的疑问。为什么在下面的代码中,只有在没有强制转换为右值引用时才会进行优化,否则将调用移动(是否提供)或复制(如果没有提供移动构造函数)构造函数。
struct Clasa{
Clasa(){
std::cout << "Default" << std::endl;
}
Clasa(const Clasa& clasa){
std::cout << "Copy" << std::endl;
}
Clasa(Clasa&& clasa){
std::cout << "Move" << std::endl;
}
~Clasa(){
std::cout << "Destructor" << std::endl;
}
};
int main(){
Clasa c = (Clasa&&)Clasa();//no optimization
Clasa d = Clasa();//move/copy elision
}
答:
4赞
user12002570
10/29/2023
#1
在第一种情况下,临时具体化发生,因为您显式绑定了对 prvalue() 的引用,因此此处没有省略。这可以从临时物化中看出:Clasa c = (Clasa&&)Clasa();
Class()
在以下情况下会发生临时物化:
- 将引用绑定到 PREnate 时;
现在来看第二种情况。Clasa d = Clasa();
C++17 及更高版本
从 C++17 开始,有强制性的复制省略。这意味着标准要求将对象直接构造到存储中,否则它将被复制/移动到该存储中。这实质上意味着此处不会观察到任何复制/移动调用。
C++ 之前的版本17
但在 C++17 之前,这可能会导致创建复制初始化的临时使用。这里更详细地解释了这一点。d
评论
(Clasa&&)Clasa();
表示具体化临时并绑定对它的引用。这明确地阻止了省略。Clasa d = Clasa();
std::move
(Clasa&&)
std::move