Компиляторам разрешено любое и все преобразования кода, которые не изменяют наблюдаемое поведение программы , путем применения как-будто правила .
Однако copy_elision является исключением из как-бы правила : компилятор может удалять вызовы конструкторов перемещения и копирования и совпадающие вызовы деструкторов временных объектов , даже если эти вызовы имеют наблюдаемые побочные эффекты . Чтобы увидеть эти побочные эффекты, вы должны использовать опцию -fno-elide-constructors
при компиляции.
На странице copy_elision мы должны взглянуть на предложение:
В операторе возврата, когда операндом является имя энергонезависимого
объект с автоматическим сроком хранения, который не является функцией
параметр или параметр предложения catch, который принадлежит к тому же классу
type (игнорируя cv-qualification) в качестве типа возврата функции. это
вариант исключения копии известен как NRVO, "названное возвращаемое значение
оптимизация».
Короче говоря, когда компилятор видит следующую структуру, он знает, что он является кандидатом на NRVO.
T FunctionName ( ... )
{
T a;
...
return a;
}
Что соответствует структуре кода вашей проблемы.
std::vector<T> foo() {
std::vector<T> result;
// populate result
{
/*
for loop with result.push_back().
ignore real code.
*/
}
return result;
}
То, что вы видите, не семантика движения, это просто NRVO.
Так что вопросы здесь не имеют никакого отношения.
const auto v = foo(); <-- will it move the vector by default?
const auto &v = foo(); <-- same question as above, assuming T is movable
Не имеет значения, является ли T
подвижным. Здесь не происходит move
.
Мы бы достигли того же результата и в компиляторе до C ++ 11 => http://coliru.stacked -crooked.com / a / 85c097f167b98b99
Для лучшего понимания посмотрите код -
http://coliru.stacked -crooked.com / a / 4b9a7e9504ab7aa8 или cat /Archive2/4b/9a7e9504ab7aa8/main.cpp
на Coliru.
Затем добавьте -fno-elide-constructors
и посмотрите подробный анализ. Там вы можете найти, когда вызывается конструктор перемещения.