Спецификатор explicit
Материал из cppreference.com
Содержание |
[править] Синтаксис
explicit
|
(1) | ||||||||
explicit ( выражение )
|
(2) | (начиная с C++20) | |||||||
выражение | — | контекстно преобразованное константное выражение типа bool |
1) Указывает, что конструктор или функция преобразования (начиная с C++11) или руководство по выводу (начиная с C++17) является явным, то есть его нельзя использовать для неявных преобразований и инициализации копированием.
2) Спецификатор explicit можно использовать с константным выражением. Функция является явной тогда и только тогда, когда это константное выражение оценивается как true.
|
(начиная с C++20) |
Спецификатор explicit может появляться только в последовательности-спецификаторов-объявления объявления конструктора или функции пр��образования (начиная с C++11) в определении их класса.
[править] Примечание
Конструктор с одним параметром не по умолчанию (до C++11), объявленный без спецификатора функции explicit, называется конструктором преобразования.
Оба конструктора (кроме копирования/перемещения) и пользовательские функции преобразования могут быть шаблонами функций; значение explicit
не меняется.
Маркер struct S { explicit (S)(const S&); // ошибка в C++20, OK в C++17 explicit (operator int)(); // ошибка в C++20, OK в C++17 }; |
(начиная с C++20) |
Макрос Т��стирования функциональности | Значение | Стандарт | Функциональность |
---|---|---|---|
__cpp_conditional_explicit |
201806L | (C++20) | explicit(bool) |
[править] Пример
Запустить этот код
struct A { A(int) { } // конструктор преобразования A(int, int) { } // конструктор преобразования (C++11) operator bool() const { return true; } }; struct B { explicit B(int) { } explicit B(int, int) { } explicit operator bool() const { return true; } }; int main() { A a1 = 1; // OK: инициализация копированием выбирает A::A(int) A a2(2); // OK: прямая инициализация выбирает A::A(int) A a3 {4, 5}; // OK: прямая инициализация списком выбирает A::A(int, int) A a4 = {4, 5}; // OK: инициализация копированием списка выбирает A::A(int, int) A a5 = (A)1; // OK: явное приведение выполняет static_cast if (a1) { } // OK: A::operator bool() bool na1 = a1; // OK: инициализация копированием выбирает A::operator bool() bool na2 = static_cast<bool>(a1); // OK: выполняет прямую инициализацию // B b1 = 1; // ошибка: инициализация копированием не учитывает B::B(int) B b2(2); // OK: прямая инициализация выбирает B::B(int) B b3 {4, 5}; // OK: прямая инициализация списком выбирает B::B(int, int) // B b4 = {4, 5}; // ошибка: инициализация копированием списка не учитывает B::B(int,int) B b5 = (B)1; // OK: явное приведение выполняет static_cast if (b2) { } // OK: B::operator bool() // bool nb1 = b2; // ошибка: инициализация копированием не учитывает B::operator bool() bool nb2 = static_cast<bool>(b2); // OK: static_cast выполняет прямую инициализацию [](...){}(a4, a5, na1, na2, b5, nb2); // может подавлять предупреждения о // "неиспользуемой переменной" }