Почему RVO и NRVO не сделаны обязательными стандартом?

Почему оптимизации RVO и NRVO не являются обязательными (если они применимы) стандартом? например Существует очень распространенный случай, когда функция создает некоторый объект и возвращает его в качестве результата. Конструкторы копирования / перемещения обычно исключаются из-за RVO / NRVO, но их все еще необходимо определить, что несколько сбивает с толку. Если бы RVO / NRVO был в стандарте, конструкторы копирования / перемещения в этом случае больше не требовались бы.

7

Решение

Стандартное удаление не требуется, поскольку это потребовало бы от всех реализаций его реализации во всех случаях.

Просто посмотрите на случай возврата-оптимизации названный-возвращаемого значения-оптимизации. Просто превращаю это:

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 может получать гарантия отказа от копирования в конкретном случае. А именно, elision требуется для копирования / перемещения в любое время, когда временный объект используется для инициализации объекта того же типа. Это позволяет вернуть неподвижный объект из функции.

2

Другие решения

Других решений пока нет …