#c #c 11
#c #c 11
Вопрос:
У меня есть код:
class Key
{
private:
// If I use the = default keyword here, the line "Key a = {};" compiles
// If I instead use Key() {}, that same line does not compile (as the constructor is private)
Key() = default;
Key(Key const amp;) = default;
Key(Key amp;amp;) = default;
Key amp; operator=(Key const amp;) = default;
Key amp; operator=(Key amp;amp;) = default;
};
int main()
{
// This line compiles when = default is used, but not when an empty constructor is used
Key a = {};
return 0;
}
В чем, в частности, разница между конструктором по умолчанию и пустым конструктором в этом конкретном экземпляре? Кроме того, я бы хотел, чтобы это НЕ компилировалось, является ли явное написание моего собственного пустого конструктора единственным способом сделать это здесь? Примечание: это было протестировано как с GCC 8.3, так и с Clang 10.0 с идентичными результатами.
Ответ №1:
Когда конструктор по умолчанию default
редактируется, до C 20, этот код компилируется, поскольку ваш класс с конструктором по умолчанию является агрегированным, и вы можете инициализировать агрегаты с помощью инициализации агрегата
Key a = {}; // interpreted as aggregate initialization and bypasses access qualifier on constructor
Этот код не будет компилироваться на C 20 или выше, поскольку конструктор по умолчанию делает его неагрегатным:
Key a = {}; // interpreted as calling a constructor, since Key is no longer an aggregate.
В этом случае компилятор пытается фактически вызвать конструктор и не может, поскольку конструктор является закрытым.
Когда у вас есть
Key() { };
Ваш класс больше не является агрегатом ни на одном диалекте C , поскольку он имеет определяемый пользователем конструктор, не используемый по умолчанию.
Комментарии:
1. В этой статье подробно рассматривается непостоянный агрегат на C с 11 по C 20.