const value and RVO
const value and RVO
假设我有这个函数:
template <class A>
inline A f()
{
A const r(/* a very complex and expensive construction */);
return r;
}
既然const
变量不能移动,那么声明r
const
是个好主意吗?请注意,返回的值不是const
。我感到不安的是,r
确实是const
,但这样声明可能不是一个好主意。然而,限定符应该帮助编译器生成更好的代码。
如这里所示,NRVO消除了return r;
行所隐含的r
的副本
#include <iostream>
struct A {
const char* name;
A( const char* name_ ):name(name_) { std::cout << "created " << name << "n"; }
A(A const&){ std::cout << "copied " << name << "n"; }
A(A &&){ std::cout << "moved " << name << "n"; }
};
A f() {
std::cout << "start of f()n";
A const r("bob");
std::cout << "body of f()n";
return r;
}
int main() {
A x = f();
}
并且main
中的副本也被消除。
如果您以其他方式阻止NRVO和RVO(例如,在使用GCC编译时使用标志-fno-elide-constructors
),const
可能会导致复制您的对象,而不是move
d。如果我们从A
:中删除复制构造函数,您可以看到这一点
#include <iostream>
struct A {
const char* name;
A( const char* name_ ):name(name_) { std::cout << "created " << name << "n"; }
//A(A const&){ std::cout << "copied " << name << "n"; }
A(A &&){ std::cout << "moved " << name << "n"; }
};
A f() {
std::cout << "start of f()n";
A const r("bob");
std::cout << "body of f()n";
return r;
}
int main() {
A x = f();
}
代码不再编译。虽然只要出现NRVO,复制构造函数就不会执行,但const
局部变量需要它的存在。
现在,NRVO需要一些东西,比如一个沿着所讨论函数的每个执行路径返回的单个变量:如果你"中止"并执行return A()
,NRVO就会被阻止,而你的const
本地变量会突然在所有返回位置强制复制。
如果class A
在您的控制之下,并且您希望通过移动返回const
对象,则可以执行
mutable bool resources_were_stolen = false;
并在CCD_ 19移动构造函数中将其设置为true
A(const A&& other) { ...; other.resources_were_stolen = true; }
~A() { if (!resources_were_stolen) ... }
事实上,析构函数可能会变成if (resources_were_stolen) some_unique_ptr.release();
,因为对象在构造和销毁过程中会失去const
的性质。
相关文章:
- C++核心准则 C35 对于接口类"A base class destructor should be either public and virtual, or protected and nonv
- 为什么C++逐位AND运算符在不同大小的操作数中表现为这样
- 为什么 Clang 不允许"and"作为函数名称?
- 位阵列上的快速AND运算
- 是否可以在 C++03 中定义'move-and-swap idiom'等效项
- BoostPython and CMake
- OpenSSL BIO and SSL_read
- Gurobi GRBModel and GRBmodel in C++
- 在 c++ 中,如何返回多个对象并从 RVO 中受益
- 在 RAII 构造中修改 RVO 值是否安全?
- std::visit and std::variant usage
- SHBrowseForFolder with BIF_BROWSEFORCOMPUTER and SHGetPathFr
- Directx12 and keystrokes
- different between int **arr =new int [ n]; and int a[i][j]?
- C++ getenv and setenv
- Inference pytorch C++ with alexnet and cv::imread image
- Visual Studio 2019 C++ and std::filesystem
- 保证逻辑 AND 表达式中的函数调用
- 当 RVO 可以应用时,为什么要按shared_ptr而不是按值返回?
- const value and RVO