首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >移动或命名返回值优化(NRVO)?

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

Stack Overflow用户
提问于 2011-06-04 08:31:33
回答 1查看 22.2K关注 0票数 50

假设我们有以下代码:

代码语言:javascript
复制
std::vector<int> f()
{
  std::vector<int> y;
  ...
  return y;
} 

std::vector<int> x = ...
x = f();

似乎编译器在这里有两种方法:

(a) NRVO:销毁x,然后构造f()来代替x。

(b)移动:在临时空间中构造f(),将f()移动到x中,销毁f()。

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-06-04 08:36:41

编译器可以NRVO到临时空间中,或者将结构移动到临时空间中。它将从那里移动到assign x

更新:

任何时候,如果你想使用rvalue引用进行优化,但对结果不太满意,那就自己创建一个跟踪其状态的示例类:

  • constructed
  • default constructed
  • moved from
  • destructed

并在测试中运行该类。例如:

代码语言:javascript
复制
#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;
}

如果有帮助,将print语句放在你感兴趣的特殊成员中(例如,复制构造函数、移动构造函数等)。

顺便说一句,如果这段代码在你身上出错了,不用担心。这对我来说也是错误的。因此,这种特殊的设计(返回一个局部变量的右值引用)不是一个好的设计。在你的系统上,它可能会打印出"A is destructed“,而不是分段错误。这将是你不想这样做的另一个信号。

票数 59
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6233879

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档