【问题标题】:Tour of C++ copy elision in Section 4.2.3 [duplicate]第 4.2.3 节中的 C++ 复制省略之旅 [重复]
【发布时间】:2020-08-08 23:02:36
【问题描述】:

我正在阅读第 4.2.3 节初始化容器,C++ 第二版教程

上面写着:

Vector read(istream& is)
{
     Vector v;
     for (double d; is>>d;)
         v.push_back(d);
     return v;
}

... 为Vector 提供移动构造函数的方法,以便从read() 返回潜在的大量数据很便宜,在第 5.2.2 节中进行了说明:

Vector v = read(cin);  // no copy of Vector elements here

是否保证上述表达式将被复制省略(在 C++17 中)? 我认为返回中的v 是一个左值和一个局部变量,所以它可以被复制省略,但不能保证被省略。 我在这里遗漏了什么吗?

【问题讨论】:

  • 在 Pre-C++17 中没有保证,在 C++17 之后的版本中得到保证。我相信有人会用大量的参考资料来回答这个问题。
  • @Croolman 是真的吗?据我所知,只有 return 语句中的纯右值才能保证在 C++17 及以后的版本中被复制省略。我不是专家,所以如果不是这样,请告诉我。
  • NRVO 在 C++17 中无法保证,因此移动构造函数仍然需要可见。
  • 或者更确切地说,这个:How does guaranteed copy elision work?
  • @JayLee Stroustrup 写道“没有元素的副本”,这是准确的。如果 NRVO 在这里不适用,则(保证会)调用移动构造函数而不是复制构造函数,根据[class.copy.elision]。因此,无论是否应用 NRVO,都可以保证元素不会受到影响。

标签: c++ c++17 move move-semantics copy-elision


【解决方案1】:

是否保证上述表达式会被复制省略(在 C++17 中)?

我认为返回中的 v 是一个左值和一个局部变量,所以它可以被复制省略,但不能保证被省略。我在这里遗漏了什么吗?

来自copy_elision

复制/移动(C++11 起)操作的非强制省略

在return语句中,当操作数是具有自动存储持续时间的非易失性对象的名称时,该对象不是函数参数或catch子句参数,并且属于同一类类型(忽略cv-限定)作为函数返回类型。这种复制省略的变体被称为 NRVO,“命名返回值优化”。

因此,即使在 C++17 中,也无法保证 NRVO。

但是,如果未应用,则移动构造函数已完成(有关详细信息,请参阅 return statement)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-07
    • 1970-01-01
    • 1970-01-01
    • 2021-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多