C++ 从函数返回const对象会阻止从外部移动构造吗?

C++ 从函数返回const对象会阻止从外部移动构造吗?,c++,move-semantics,C++,Move Semantics,给定此函数和函数调用: std::string GetString() { std::stringstream sstr; const auto str = sstr.str(); return str; } const auto returnedStr = GetString(); 当我将str声明为const时,是否会省略move构造?在您的情况下,returnedStr将从GetString()的返回值进行move构造,但该返回值将从str(1)复制构造。如果str不是co

给定此函数和函数调用:

std::string GetString() {
  std::stringstream sstr;
  const auto str = sstr.str();
  return str;
}

const auto returnedStr = GetString();

当我将
str
声明为const时,是否会省略move构造?

在您的情况下,
returnedStr
将从
GetString()
的返回值进行move构造,但该返回值将从
str
(1)复制构造。如果
str
不是
const
,则返回值将由它构成

请注意,在这两种情况下,返回值优化仍然适用,因此编译器仍然可以直接在
returnedStr
的空间中构造返回值(甚至
str
本身),跳过一个或两个复制/移动构造。这是由C++11 12.8/31授予的:

当满足某些条件时,允许实现省略类的复制/移动构造 对象,即使该对象的复制/移动构造函数和/或析构函数有副作用。在这种情况下, 该实现将省略的复制/移动操作的源和目标视为两个不同的操作 指代同一对象的方式,并且该对象的销毁发生在时间较晚的时候 如果没有优化,两个对象将被破坏。这种对复制/移动的省略 在以下情况下允许进行称为复制省略的操作 消除多个副本):

  • 在具有类返回类型的函数中的
    return
    语句中,当表达式是 具有相同cv的非易失性自动对象(函数或catch子句参数除外) 类型作为函数返回类型,可以通过构造 自动对象直接输入函数的返回值

  • 复制/移动未绑定到引用(12.2)的临时类对象时 对于具有相同cv类型的类对象,可以通过 将临时对象直接构造到省略的复制/移动的目标中

第一个要点包括省略返回值构造,另一个要点包括将返回值移动到
returnedStr
。请注意“相同cv不合格”类型的要求,这意味着无论cv限定符如何,这都有效



(1) 请注意,如果我们讨论的是一个类
X
,而不是
std::string
,它提供了一个移动构造函数,该构造函数接受
常量X&&
,那么返回值实际上将使用该构造函数进行移动构造(不管它可能具有何种语义).

安吉的答案是对的,但谁能记住律师的所有语言规则呢

为了让我更容易记住,我从STL自己的口中写了以下规则

  • 不要将本地人作为常量返回[16]
  • $禁止移动语义

  • 按的值返回本地时不使用移动 完全相同的类型[16]
  • 如果您这样做,$NVRO将不会被使用

  • 不通过右值引用(&&)返回[16]
  • 除非你真的知道自己在做什么

    注:


    [16] 不要帮助编译器,使用本机2013,

    @PiotrS。补充道,尽管我认为答案并不需要。这只是正常的工作中的复制省略。不错,但我不是指省略的要求,而是常规的返回,
    X(const X&&)
    是一个有效的移动构造函数,如果声明了,将调用该构造函数,即使它不合理类X的非模板构造函数是移动构造函数,如果其第一个参数的类型为X&&、常量X&&、volatile X&&或const volatile X&&,并且没有其他参数,或者所有其他参数都有默认参数“@PiotrS。对于退货,我认为更不需要标准报价<代码>标准::字符串没有声明标准::字符串(const std::string&)ctor,所以无法移动,句号。谢谢,这就是我喜欢我的答案的方式:)