Почему 'A a{};' компилировать, когда конструктор по умолчанию A::A() удален?

Вот пример кода в вопросе:

struct A {
    A() = delete;
};

int main()
{
//  A a(); // compiles, since it's a function declaration (most vexing parse)
//  A a;   // does not compile, just as expected
    A a{}; // compiles, why? The default constructor is deleted.
}

Попробуйте здесь с любым из доступных компиляторов. Я пробовал с несколькими и не нашел тот, который дал ошибку компиляции.

2 ответа

Решение

Это актуальная языковая проблема, которая, скорее всего, будет исправлена ​​в ближайшее время. Предложение, которое касается необходимого изменения дизайна, можно найти здесь. Из аннотации предложения:

C++ в настоящее время позволяет инициализировать некоторые типы с объявленными пользователем конструкторами через агрегатную инициализацию, минуя эти конструкторы. В результате получается удивительный, запутанный и ошибочный код

Так как A является агрегатным типом, тогда A a{}; инициализация агрегата выполнена.

каждый direct public base, (since C++17) Элемент массива или нестатический член класса в порядке индекса / появления массива в определении класса инициализируется копией из соответствующего предложения списка инициализатора.

В агрегатной инициализации каждый член или элемент (если таковой имеется) будет инициализироваться копией напрямую, конструктор обходится; так что это deleteЭд или нет, не имеет значения.

Обратите внимание, что явно удаленные конструкторы разрешены для агрегатных типов (начиная с C++11) (до C++20),

не предоставленные пользователем конструкторы (конструкторы по умолчанию или удаленные допускаются) (начиная с C++11) (до C++17)

не предоставленные пользователем, унаследованные или явные конструкторы (конструкторы по умолчанию или удаленные конструкторы допускаются) (начиная с C++17) (до C++ 20)

Другие вопросы по тегам