Namespaces
Variants

Converting constructor

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

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

В отличие от явных конструкторов, которые рассматриваются только при прямой инициализации (которая включает явные преобразования , такие как static_cast ), преобразующие конструкторы также рассматриваются при копирующей инициализации , как часть пользовательской последовательности преобразований .

Говорится, что преобразующий конструктор задаёт неявное преобразование из типов его аргументов (если они есть) в тип его класса. Заметьте, что не-явный пользовательская функция преобразования также задаёт неявное преобразование.

Неявно объявленные и пользовательские не- explicit конструкторы копирования и конструкторы перемещения являются преобразующими конструкторами.

Пример

struct A
{
    A() { }         // converting constructor (since C++11)  
    A(int) { }      // converting constructor
    A(int, int) { } // converting constructor (since C++11)
};
struct B
{
    explicit B() { }
    explicit B(int) { }
    explicit B(int, int) { }
};
int main()
{
    A a1 = 1;      // OK: copy-initialization selects A::A(int)
    A a2(2);       // OK: direct-initialization selects A::A(int)
    A a3{4, 5};    // OK: direct-list-initialization selects A::A(int, int)
    A a4 = {4, 5}; // OK: copy-list-initialization selects A::A(int, int)
    A a5 = (A)1;   // OK: explicit cast performs static_cast, direct-initialization
//  B b1 = 1;      // error: copy-initialization does not consider B::B(int)
    B b2(2);       // OK: direct-initialization selects B::B(int)
    B b3{4, 5};    // OK: direct-list-initialization selects B::B(int, int)
//  B b4 = {4, 5}; // error: copy-list-initialization selected an explicit constructor
                   //        B::B(int, int)
    B b5 = (B)1;   // OK: explicit cast performs static_cast, direct-initialization
    B b6;          // OK, default-initialization
    B b7{};        // OK, direct-list-initialization
//  B b8 = {};     // error: copy-list-initialization selected an explicit constructor
                   //        B::B()
    [](...){}(a1, a4, a4, a5, b5); // may suppress "unused variable" warnings
}

Смотрите также