Вопрос

Я недавно заметил класс в C ++ 0x, который требует явного конструктора по умолчанию. Однако я не в состоянии придумать сценарий, в котором конструктор по умолчанию можно назвать неявно. Похоже, довольно бессмысленный спецификатор. Я думал, что, может быть, это запрещено Class c; в пользу Class c = Class(); Но это не похоже на случай.

Некоторые соответствующие цитаты из C ++ 0x FCD, поскольку мне легче навигаться [Подобный текст существует в C ++ 03, если не в тех же местах

12.3.1.3 [CLASS.CONV.CTOR

Конструктор по умолчанию может быть явным конструктором; Такой конструктор будет использоваться для выполнения инициализации инициализации значения или значения (8.5).

Он продолжает привести пример явного конструктора по умолчанию, но он просто имитирует пример, который я предоставил выше.

8.5.6 [DECL.INIT

Для инициализации по умолчанию объект типа T означает:

- Если T - это (возможно, квалифицированный CV) тип класса (пункт 9), конструктор по умолчанию для t вызывается (и инициализация плохо образуется, если T не имеет доступного конструктора по умолчанию);

8.5.7 [DECL.INIT

Для значения - инициализация объекта типа T означает:

. );

В обоих случаях стандартные вызовы для вызываемого конструктора по умолчанию. Но это произойдет, если бы конструктор по умолчанию не были явными. Для полноты Сайка:

8.5.11 [DECL.INIT

Если для объекта не указано инициализатора, объект - инициализируется по умолчанию;

От того, что я могу сказать, это просто листья преобразования из данных. Который не имеет смысла. Лучшее, что я могу придумать, будет следующим:

void function(Class c);
int main() {
  function(); //implicitly convert from no parameter to a single parameter
}

Но, очевидно, это не так, чтобы C ++ обрабатывает аргументы по умолчанию. Что еще, что сделало бы explicit Class(); вести себя по-разному Class();?

Конкретный пример, который генерировал этот вопрос, было std::function 20.8.14.2 func.wrap.func. Это требует нескольких конвертационных конструкторов, ни один из которых из которых не помечены явным, но конструктор по умолчанию.

Это было полезно?

Решение

Это объявляет явный конструктор по умолчанию:

struct A {
  explicit A(int a1 = 0);
};

A a = 0; /* not allowed */
A b; /* allowed */
A c(0); /* allowed */

В случае отсутствия параметра нет, как в следующем примере, explicit избыточно

struct A {
  /* explicit is redundant. */
  explicit A();
};

В некоторой черновике C ++ 0x (я считаю, что это было N3035), это имело значение следующим образом:

A a = {}; /* error! */
A b{}; /* alright */

void function(A a);
void f() { function({}); /* error! */ }

Но в FCD они изменил это (Хотя я подозреваю, что у них не было этой особой причины) в том, что все три случая ценность инициализация соответствующий объект. Значение-инициализация не делает танец разрешения перегрузки и, таким образом, не будет провалиться на явных конструкторах.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top