C++ 移动或命名返回值优化(NRVO)?

C++ 移动或命名返回值优化(NRVO)?,c++,optimization,c++11,move-semantics,return-value-optimization,C++,Optimization,C++11,Move Semantics,Return Value Optimization,假设我们有以下代码: std::vector<int> f() { std::vector<int> y; ... return y; } std::vector<int> x = ... x = f(); std::vector f() { std::向量y; ... 返回y; } 向量x=。。。 x=f(); 编译器似乎有两种方法: (a) NRVO:解构x,然后构造f()来代替x。 (b) 移动:在临时空间中构造f(),将f()移动

假设我们有以下代码:

std::vector<int> f()
{
  std::vector<int> y;
  ...
  return y;
} 

std::vector<int> x = ...
x = f();
std::vector f()
{
std::向量y;
...
返回y;
} 
向量x=。。。
x=f();
编译器似乎有两种方法:

(a) NRVO:解构x,然后构造f()来代替x。
(b) 移动:在临时空间中构造f(),将f()移动到x,析构函数f()


根据标准,编译器可以自由使用这两种方法吗?

编译器可以将NRVO放入临时空间,或者将构造移动到临时空间。它将从那里移动分配
x

更新:

当您试图使用右值引用进行优化时,如果您对结果不满意,请创建一个示例类来跟踪其状态:

  • 建造
  • 默认构造
  • 破坏
并通过测试运行该类。例如:

#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\n";
            break;
        case A::moved_from:
            os << "A is moved from\n";
            break;
        case A::default_constructed:
            os << "A is default constructed\n";
            break;
        default:
            os << "A = " << a.state_ << '\n';
            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;
}
#包括
#包括
甲级
{
int state_u2;;
公众:
枚举{destructed=-2,从中移动,默认为构造};
A():状态{(默认构建){
A(常数A&A):状态{A.state}
A&operator=(const A&A){state\uu=A.state\uu;return*this;}
A(A&&A):状态{A.state}
A&运算符=(A&&A)
{state\uu=a.state;a.state\uu=moved\u from;return*this;}
~A(){state\=destructed;}
显式A(int-s):状态{assert(state_u>default_-constructed)}
朋友
std::ostream&

接线员(a)不允许。除了必须调用赋值运算符之外,当
f
中的
..
的某个部分抛出异常时,它会有错误的行为。
x
在这种情况下不应更改,因此如果它已经被破坏,这是一个问题。这是一个模糊问题的问题。我认为he并不是指他字面上写的东西。显然其他人也这么认为。我在回答中故意使用OP的术语。标准力求精确,但它是一个糟糕的教程。我没有(现在仍然没有)认识到我的含糊不清。这当然是一个我无法避免的常见错误。如果我知道我的答案的哪些部分是含糊不清的,我会很高兴地澄清。我的目标是传播知识,而不是让它变得混乱。我有一个类似的示例类来解决这一点!除了我使用断点和printfs。