7

为什么标准不强制规定 RVO 和 NRVO 优化(当它们适用时)?例如,当一个函数产生一些对象并将其作为结果返回时,这是一种非常常见的情况。由于 RVO/NRVO,复制/移动构造函数通常被省略,但它们仍然需要定义,这有点令人困惑。如果 RVO/NRVO 在标准中,则在这种情况下将不再需要复制/移动构造函数。

4

1 回答 1

2

标准不要求复制省略,因为这将要求所有实现在所有情况下都实现它。

只需看一下返回值优化与命名返回值优化的情况。简单地转这个:

std::string Func()
{
  return std::string("foo");
}

进入这个功能相同的代码:

std::string Func()
{
  std::string named("foo");
  return named;
}

后者比前者需要更多的编译器。不同的编译器在不同的情况下支持 NRVO。当然,在这个微不足道的情况下,他们中的大多数人都支持它,但是那里有很多不同的情况。在某些情况下,编译器只是说“搞砸了”,并没有完全进行优化。

您的方式将需要以下之一:

  1. 在所有适用的情况下强制执行复制省略,无论编译器实现多么困难。所以现在每个编译器编写者都必须处理这样的情况:

    std::string Func(bool b)
    {
      if(b)
      {
        std::string named("foo");
        return named;
      }
      else
      {
        std::string named("bar");
        return named;
      }
    }
    

    在这些情况下,许多编译器不处理 NRVO。这是一个简单的案例;它们可以变得比这复杂得多。

  2. 遍历每个编译器并找到始终使用复制省略的常见情况子集,然后在标准中将它们指定为要求。这太荒谬了;您将根据实施细节进行标准化。这从来都不是一件好事。

请注意,在特定情况下,C++17 可能会保证复制省略。即,任何时候使用临时对象初始化相同类型的对象时,复制/移动都需要省略。这使得从函数返回固定对象成为可能。

于 2013-08-31T00:53:29.577 回答