Конструктор по умолчанию с пустыми скобками

Есть ли веская причина, что пустой набор круглых скобок (скобки) недействителен для вызова конструктора по умолчанию в C ++?

MyObject object; // ok - default ctor MyObject object(blah); // ok MyObject object(); // error 

Кажется, я набираю «()» автоматически каждый раз. Есть ли веская причина, что это запрещено?

Самый неприятный синтаксический анализ

Это связано с тем, что называется «самым неприятным анализом на C ++». В принципе, все, что может интерпретировать компилятор как объявление функции, будет интерпретироваться как объявление функции.

Другой пример той же проблемы:

 std::ifstream ifs("file.txt"); std::vector v(std::istream_iterator(ifs), std::istream_iterator()); 

v интерпретируется как объявление функции с двумя параметрами.

Обходной путь состоит в том, чтобы добавить еще одну пару круглых скобок:

 std::vector v((std::istream_iterator(ifs)), std::istream_iterator()); 

Или, если у вас есть C ++ 11 и инициализация списка (также известная как равномерная инициализация):

 std::vector v{std::istream_iterator{ifs}, std::istream_iterator{}}; 

При этом нет способа интерпретировать его как объявление функции.

Потому что он рассматривается как объявление для функции:

 int MyFunction(); // clearly a function MyObject object(); // also a function declaration 

Тот же синтаксис используется для объявления функции – например, object функции, без параметров и возврата MyObject

Поскольку компилятор считает, что это объявление функции, которая не принимает аргументов и возвращает экземпляр MyObject.

Вы также можете использовать более подробный способ построения:

 MyObject object1 = MyObject(); MyObject object2 = MyObject(object1); 

В C ++ 0x это также позволяет auto :

 auto object1 = MyObject(); auto object2 = MyObject(object1); 

Я думаю, компилятор не знал бы, будет ли это утверждение:

Объект MyObject ();

это вызов конструктора или прототип функции, объявляющий функцию с именем object с возвращаемым типом MyObject и без параметров.

Как уже упоминалось много раз, это декларация. Это способ обратной совместимости. Одна из многих областей C ++, которая является тупой / непоследовательной / болезненной / фиктивной из-за ее наследия.

От n4296 [dcl.init]:

[ Заметка:
Поскольку () не разрешен синтаксисом инициализатора , X a(); не является объявлением объекта classа X, а объявлением функции , не принимающей аргумент и возвращающей X. Форма () разрешена в некоторых других контекстах инициализации (5.3.4, 5.2.3, 12.6.2).
-End note]

Как говорили другие, это объявление функции. Начиная с C ++ 11 вы можете использовать инициализацию скобки, если вам нужно увидеть пустое то, что явно указывает вам, что используется конструктор по умолчанию.

 Jedi luke{}; //default constructor 
  • Можно ли вызвать конструктор из другого конструктора (сделать цепочку конструктора) в C ++?
  • Java: доступ к частному конструктору с параметрами типа
  • Delphi: Понимание конструкторов
  • Сеттерные методы или конструкторы
  • Почему защищенный конструктор вызывает ошибку в этом коде?
  • Есть ли неявный конструктор по умолчанию в C ++?
  • конструктор в качестве делегата - возможно ли это на C #?
  • механизм вызова конструктора
  • избегая скуки факультативных параметров
  • В любом случае, @Autowire bean, который требует аргументов конструктора?
  • Сколько работы должно быть сделано в конструкторе?
  • Давайте будем гением компьютера.