Пространства имён
Варианты
Действия

Спецификатор explicit

Материал из cppreference.com
< cpp‎ | language
 
 
 
 

Содержание

[править] Синтаксис

explicit (1)
explicit ( выражение ) (2) (начиная с C++20)
выражение контекстно преобразованное константное выражение типа bool
1) Указывает, что конструктор или функция преобразования (начиная с C++11) или руководство по выводу (начиная с C++17) является явным, то есть его нельзя использовать для неявных преобразований и инициализации копированием.
2) Спецификатор explicit можно использовать с константным выражением. Функция является явной тогда и только тогда, когда это константное выражение оценивается как true.
(начиная с C++20)

Спецификатор explicit может появляться только в последовательности-спецификаторов-объявления объявления конструктора или функции пр��образования (начиная с C++11) в определении их класса.

[править] Примечание

Конструктор с одним параметром не по умолчанию (до C++11), объявленный без спецификатора функции explicit, называется конструктором преобразования.

Оба конструктора (кроме копирования/перемещения) и пользовательские функции преобразования могут быть шаблонами функций; значение 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); // может подавлять предупреждения о
                                     // "неиспользуемой переменной"
}

[править] Смотрите также