问题描述
假设我们有以下代码:
std::vector<int> f()
{
std::vector<int> y;
...
return y;
}
std::vector<int> x = ...
x = f();
这里的编译器似乎有两种方法:
It seems the compiler has two approaches here:
(a) NRVO:破坏 x,然后构造 f() 代替 x.
(b) 移动:在临时空间构造 f(),将 f() 移动到 x,析构 f().
(a) NRVO: Destruct x, then construct f() in place of x.
(b) Move: Construct f() in temp space, move f() into x, destruct f().
根据标准,编译器是否可以自由使用任一方法?
Is the compiler free to use either approach, according to the standard?
推荐答案
编译器可能会将 NRVO 放入临时空间,或者将构造移动到临时空间.从那里它会移动assign x.
The compiler may NRVO into a temp space, or move construct into a temp space. From there it will move assign x.
更新:
任何时候您想使用右值引用进行优化,并且您对结果不满意时,请为自己创建一个跟踪其状态的示例类:
Any time you're tempted to optimize with rvalue references, and you're not positive of the results, create yourself an example class that keeps track of its state:
- 构建
- 默认构造
- 搬离
- 销毁
并通过测试运行该类.例如:
And run that class through your test. For example:
#include <iostream>
#include <cassert>
class A
{
int state_;
public:
enum {destructed = -2, moved_from, default_constructed};
A() : state_(default_constructed) {}
A(const A& a) : state_(a.state_) {}
A& operator=(const A& a) {state_ = a.state_; return *this;}
A(A&& a) : state_(a.state_) {a.state_ = moved_from;}
A& operator=(A&& a)
{state_ = a.state_; a.state_ = moved_from; return *this;}
~A() {state_ = destructed;}
explicit A(int s) : state_(s) {assert(state_ > default_constructed);}
friend
std::ostream&
operator<<(std::ostream& os, const A& a)
{
switch (a.state_)
{
case A::destructed:
os << "A is destructed
";
break;
case A::moved_from:
os << "A is moved from
";
break;
case A::default_constructed:
os << "A is default constructed
";
break;
default:
os << "A = " << a.state_ << '
';
break;
}
return os;
}
friend bool operator==(const A& x, const A& y)
{return x.state_ == y.state_;}
friend bool operator<(const A& x, const A& y)
{return x.state_ < y.state_;}
};
A&& f()
{
A y;
return std::move(y);
}
int main()
{
A a = f();
std::cout << a;
}
如果有帮助,请将打印语句放在您感兴趣的特殊成员中(例如复制构造函数、移动构造函数等).
If it helps, put print statements in the special members that you're interested in (e.g. copy constructor, move constructor, etc.).
顺便说一句,如果这对您造成了错误,请不要担心.它对我来说也是段错误.因此,这种特殊设计(返回对局部变量的右值引用)不是一个好的设计.在您的系统上,它可能会打印出A is destructed"而不是段错误.这将是您不想这样做的另一个迹象.
Btw, if this segfaults on you, don't worry. It segfaults for me too. Thus this particular design (returning an rvalue reference to a local variable) is not a good design. On your system, instead of segfaulting, it may print out "A is destructed". This would be another sign that you don't want to do this.
这篇关于移动或命名返回值优化 (NRVO)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!


大气响应式网络建站服务公司织梦模板
高端大气html5设计公司网站源码
织梦dede网页模板下载素材销售下载站平台(带会员中心带筛选)
财税代理公司注册代理记账网站织梦模板(带手机端)
成人高考自考在职研究生教育机构网站源码(带手机端)
高端HTML5响应式企业集团通用类网站织梦模板(自适应手机端)