Стандарт C ++ 11 гласит, что если выполняются условия для исключения копирования ( §12.8 / 31
) , реализация должна рассматривать return
ed локальную переменную lvalue и параметры функции как rvalue сначала (перемещение), а если разрешение перегрузки не удается, как подробно описано, затем обрабатывает его как lvalue (копия) .
§12.8 [class.copy] p32
Когда критерии исключения операции копирования выполнены или будут выполнены, за исключением того факта, что исходный объект является параметром функции, и объект, который должен быть copied обозначается lvalue, разрешение перегрузки для выбора конструктора для копии сначала выполняется, как если бы объект был обозначен rvalue . Если разрешение перегрузки не удается или если тип первого параметра выбранного конструктора не является ссылкой rvalue на тип объекта (возможно, cv-квалифицированным), разрешение перегрузки выполняется снова, рассматривая объект как lvalue. [ Примечание: Это двухэтапное разрешение перегрузки должно выполняться независимо от того, произойдет ли исключение копирования. Он определяет конструктор, который должен быть вызван, если исключение не выполняется, и выбранный конструктор должен быть доступен, даже если вызов отклонен. —в конце примечания ]
Включает ли это также подобъекты элементов? Я тестировал следующий фрагмент:
#include
struct traced{
traced(){ std::cout << "default ctor\n"; }
traced(traced const&){ std::cout << "copy ctor\n"; }
traced(traced&&){ std::cout << "move ctor\n"; }
};
struct X{
traced t;
};
traced f(){
X x;
return x.t;
}
int main(){
traced t = f();
}
Живой пример на Ideone. И ни GCC 4.7 ToT, ни Clang 3.1 ToT не будут отображать "move ctor", что наводит меня на мысль, что стандарт не включает подобъекты-члены.
Я что-то упустил? Мой тестовый код не работает? Что именно заставляет вывод быть таким, какой он есть?