3

一般来说,我想知道现代编译器何时以及为什么使用 c++11 的 gcc 4.7 及更高版本不能应用 NVRO 优化。

编辑:我错误地过度简化了这段代码,没有返回任何局部变量。下面的@cooky451 提供了一个更好的示例,请参见ideone.com/APySue

我看到了一些代码片段来回答其他问题

A f(A&& v)
{
  return v;
}

他们被改为

A f(A&& v)
{
  return std::move(v);
}

因为他们说传递给左值 v 的右值仍然是右值并且可以移动。然而,其他人写道,这将取消 NVRO 的能力。这是吗?如果编译器知道正在返回一个临时对象,它不能直接在原地构造它而不移动任何东西吗?我想我不明白为什么案例一会有 NVRO 而不是案例 2。我可能有错误的事实,因此问题。另外,由于这个原因,我读到案例 2 是一种反模式,您不应该像这样返回 std::move 。任何额外的见解都会有所帮助。有人告诉我,编译器将在幕后创建如下所示的内容: A&__hidden__是对函数的赋值,在这种情况下是 myValue。

A myValue = f(A());

// behind the scenes pseudo code for direct in place construction

void f(A&& v,  A& __hidden__ )
{
    __hidden__ = v;
    return;
}
4

1 回答 1

1

两者都不会使用 RVO,因为这是不可能的。问题是: && 仍然只是一个参考。您返回的变量不在您的函数局部范围内!所以,没有 std::move,你会复制,然后你会移动。只要您不编写移动构造函数/赋值运算符或一些完美转发模板代码,我建议顺便说一句不要期望每个右值引用有什么东西。只看价值。在某些情况下,它的开销很小,但实际上并不重要。它使代码更具可读性。而且更简单,因为调用者可以复制或移动参数,并且您不必提供额外的 const& 重载。

于 2013-09-07T19:30:44.507 回答