Подтвердить что ты не робот

Возможная ошибка при обработке ключевого слова `default` в VS2015 С++

При тестировании компилятора VS2015 С++ я наткнулся на странную ошибку с ключевым словом default. Если я это сделаю:

struct Dummy
{
    Dummy() = default;
    Dummy(const Dummy &) = delete;
};  

int main()
{
    const Dummy& ref = Dummy();
    return 0;
}

Я получаю

ошибка C2280: 'Dummy:: Dummy (const Dummy &)': попытка ссылки на удаленную функцию
примечание: см. объявление "Dummy:: Dummy"

Но если я использую пустой конструктор

struct Dummy
{
    Dummy() {}
    Dummy(const Dummy &) = delete;
};

int main()
{
    const Dummy& ref = Dummy();
    return 0;
}

Код компилируется. Запуск первого примера с g++ или clang не вызывает ошибок.

Почему использование конструктора по умолчанию с VS2015 попытается использовать конструктор копирования, где он не находится в g++ или clang?

4b9b3361

Ответ 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 (пожалуйста, проголосуйте)