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



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



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

MyObject object(); // error


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

624   9  

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

    Ничего не найдено.