Почему оптимизации RVO и NRVO не являются обязательными (если они применимы) стандартом? например Существует очень распространенный случай, когда функция создает некоторый объект и возвращает его в качестве результата. Конструкторы копирования / перемещения обычно исключаются из-за RVO / NRVO, но их все еще необходимо определить, что несколько сбивает с толку. Если бы RVO / NRVO был в стандарте, конструкторы копирования / перемещения в этом случае больше не требовались бы.
Стандартное удаление не требуется, поскольку это потребовало бы от всех реализаций его реализации во всех случаях.
Просто посмотрите на случай возврата-оптимизации названный-возвращаемого значения-оптимизации. Просто превращаю это:
std::string Func()
{
return std::string("foo");
}
В это функционально идентичный код:
std::string Func()
{
std::string named("foo");
return named;
}
Последний требует гораздо больше от компилятора, чем первый. Различные компиляторы поддерживают NRVO в разных обстоятельствах. Конечно, большинство из них поддерживают это в этом тривиальном случае, но есть много разных случаев там. И в некоторых случаях компиляторы просто говорят «винт это» и не выполняют оптимизацию вообще.
Ваш путь потребует одного из следующих:
Чтобы обеспечить исключение копирования во всех применимых случаях, независимо от того, насколько сложно это реализовать для компиляторов. Так что теперь каждый автор компилятора должен иметь дело с такими случаями:
std::string Func(bool b)
{
if(b)
{
std::string named("foo");
return named;
}
else
{
std::string named("bar");
return named;
}
}
Многие компиляторы не обрабатывают NRVO в этих случаях. И это просто дело; они могут стать намного сложнее, чем это.
Просмотрите каждый компилятор и найдите общее подмножество случаев, в которых всегда используется разрешение копирования, а затем укажите их в стандарте в качестве требований. Это совершенно нелепо; вы будете стандартизировать на основе детали реализации. Это никогда не хорошо.
Обратите внимание, что C ++ 17 может получать гарантия отказа от копирования в конкретном случае. А именно, elision требуется для копирования / перемещения в любое время, когда временный объект используется для инициализации объекта того же типа. Это позволяет вернуть неподвижный объект из функции.
Других решений пока нет …