我阅读了更多相关文章,但没有一个答案能够澄清我的疑虑。为什么在下面的代码中,仅当没有转换为右值引用时才会进行优化,否则将调用移动(无论是否提供)或复制(如果没有提供移动构造函数)构造函数。
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
}
最佳答案
在第一种情况下,Clasa c = (Clasa&&)Clasa();
临时物化发生在您显式绑定(bind)对纯右值的引用(Class()
),因此这里没有省略。这可以从temporary materialization看出:
Temporary materialization occurs in the following situations:
- when binding a reference to a prvalue;
现在来看Clasa d = Clasa();
的第二种情况。
C++17 及以上版本
从 C++17 开始有 mandatory copy elision 。这意味着标准强制要求将对象直接构造到存储中,否则它将被复制/移动到存储中。这本质上意味着这里不会观察到复制/移动调用。
C++17 之前版本
但在 C++17 之前,这可能会导致创建一个临时对象,使用该临时对象来复制初始化。同样更详细地解释了here .
关于c++ - 转换为右值引用可防止复制省略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77383403/