#include<iostream>
using namespace std;
struct B{};
struct A
{
A(const B &)
{
cout<<"A(const B &)"<<endl;
}
A(B &&)
{
cout<<"A(B &&)"<<endl;
}
};
A get()
{
B b;
return b;
}
int main()
{
get();
}
Я тестировал код с VC++ 14,2 и GCC 5.4.0, оба из них выход:Почему в этом случае вызывается конструктор ссылок r-value?
A(B &&)
Почему выход не
A(const B &)
?
Имеет ли этот код какое-либо отношение к copy elision
? (Но A и B - разные типы, поэтому copy elision
не должен работать здесь)
Это действительно очень интересный вопрос. Я считаю, что формулировка в 12.8/32 несколько неясна: неясно, должен ли тип возвращаемого выражения быть таким же, как тип возврата функции, чтобы правило применялось. Я думаю, вы могли бы прочитать его, как если бы * любой возвращаемый объект с автоматическим хранилищем считался обозначенным rvalue. Различные компиляторы [думают по-другому об этом] (http://melpon.org/wandbox/permlink/meIAgmvSOVq435vy). –
[CWG1579] (http://wg21.link/cwg1579) кажется актуальным здесь. –
@KerrekSB в соответствии с (31.1), 'когда выражение является именем энергонезависимым автоматическим объектом (кроме параметра функции или переменной, введенной объявлением исключения обработчика (15.3)) с тем же типом (игнорируя cv-qualification) как функцию return type', я думаю, что 'тот же тип' должен быть точно таким же, как' return type'. Это означает, что 'copy elision' будет работать, если я возвращу объект' A'. Но неявное преобразование из 'B' в' A' происходит до того, как 'copy elision',' copy elision' не должно влиять на 'implicit conversion'. – Caesar