假设我们有以下代码:
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模板网!
fpermissive 标志有什么作用?What does the fpermissive flag do?(fpermissive 标志有什么作用?)
如何在我不想编辑的第 3 方代码中禁用来自 gccHow do you disable the unused variable warnings coming out of gcc in 3rd party code I do not wish to edit?(如何在我不想编辑的第 3 方代码中禁
使用 GCC 预编译头文件Precompiled headers with GCC(使用 GCC 预编译头文件)
如何在 OS X 中包含 omp.h?How to include omp.h in OS X?(如何在 OS X 中包含 omp.h?)
如何让 GCC 将 .text 部分编译为可写在 ELF 二进制文How can I make GCC compile the .text section as writable in an ELF binary?(如何让 GCC 将 .text 部分编译为可写在 ELF 二进制文件中?)
GCC、字符串化和内联 GLSL?GCC, stringification, and inline GLSL?(GCC、字符串化和内联 GLSL?)