Ответ 1
Это определенно ошибка в VS 2015.
В С++ 11 назначение временной ссылки const не должно вызывать конструктор копирования, но VS 2015 делает.
Вы можете проверить его с помощью
#include <iostream>
struct Dummy
{
Dummy() = default;
Dummy(const Dummy &) { std::cout << "copy ctor" << std::endl; }
void test() const { std::cout << "test" << std::endl; }
};
int main()
{
const Dummy& ref = Dummy();
ref.test();
return 0;
}
составленный на VS 2013, 2015, gcc и clang. Только VS (любая версия) вызывает конструктор копирования, если конструктор класса определяется как = default
.
Я думаю, что VS compiiler еще в 2015 году ошибочно использует старые стандартные правила С++ 03 для этого (8.5.3.5 из С++ 03):
Если выражение инициализатора представляет собой rvalue, а T2 - тип класса и "cv1 T1" является ссылочным-совместимым с "cv2 T2", ссылка привязана одним из следующих способов (выбор определяется реализацией):
- Ссылка привязана к объекту, представленному rvalue (см. 3.10), или к под-объекту внутри этого объекта.
- Создается временный тип "cv1 T2" [sic], и вызывается конструктор для копирования всего объекта rvalue во временный. ссылка привязана к временному или к под-объекту в пределах временный характер.
Конструктор, который будет использоваться для создания копии, может быть вызван действительно ли копия действительно выполнена.
VS разработчики выбрали второй путь. Они скорректировали это для пустого определяемого пользователем конструктора ({}
), но забыли сделать это для дефолтных конструкторов (= default
).
PS. Ошибка в MS Connect (пожалуйста, проголосуйте)