Почему '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)