为什么标准没有规定RVO和NRVO是强制性的

Why RVO and NRVO are not made obligatory by the standard?

本文关键字:NRVO 强制性 RVO 标准 为什么      更新时间:2023-10-16

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

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

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

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可能会得到拷贝省略的保证。也就是说,每当使用临时对象初始化相同类型的对象时,复制/移动都需要省略。这使得从函数返回不动对象成为可能。