Конструктор по умолчанию с пустыми скобками
есть ли веская причина, по которой пустой набор круглых скобок (скобок) недопустим для вызова конструктора по умолчанию в C++?
MyObject object; // ok - default ctor
MyObject object(blah); // ok
MyObject object(); // error
Я, кажется, набираю "() " автоматически каждый раз. Есть ли веская причина, по которой это запрещено?
9 ответов:
самый досадный разбор
это связано с тем, что известно как "самый неприятный разбор C++". В принципе, все, что может быть интерпретировано компилятором как объявление функции, интерпретируется как объявление функции.
другой пример той же проблемы:
std::ifstream ifs("file.txt"); std::vector<T> v(std::istream_iterator<T>(ifs), std::istream_iterator<T>());
vинтерпретируется как объявление функции с 2 параметрами.решение добавить еще одну пару скобки:
std::vector<T> v((std::istream_iterator<T>(ifs)), std::istream_iterator<T>());или, если у вас есть C++11 и инициализация списка (также известная как равномерная инициализация):
std::vector<T> v{std::istream_iterator<T>{ifs}, std::istream_iterator<T>{}};С этим, нет никакого способа, которым это могло бы быть интерпретировано как объявление функции.
потому что это рассматривается как объявление функции:
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();не является объявлением объект класса X, но объявление функции не принимая никаких аргументов и возвращая X. форма () разрешена в некоторых других контекстах инициализации (5.3.4, 5.2.3, 12.6.2).
-конец Примечание ]
Как говорили другие, это объявление функции. Начиная с C++11 вы можете использовать инициализацию скобки, если вам нужно увидеть пустое что-то что явно говорит вам, что используется конструктор по умолчанию.
Jedi luke{}; //default constructor
Comments