Цель явных конструкторов по умолчанию
-
26-09-2019 - |
Вопрос
Я недавно заметил класс в 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 они изменил это (Хотя я подозреваю, что у них не было этой особой причины) в том, что все три случая ценность инициализация соответствующий объект. Значение-инициализация не делает танец разрешения перегрузки и, таким образом, не будет провалиться на явных конструкторах.