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) 라고 합니다.

명시적 생성자(explicit constructors)가 직접 초기화(direct initialization) (여기에는 명시적 변환(explicit conversions) , 예를 들어 static_cast 등이 포함됨) 동안에만 고려되는 반면, 변환 생성자(converting constructors)는 복사 초기화(copy initialization) 동안에도 고려되며, 이는 사용자 정의 변환 순서(user-defined conversion sequence) 의 일부로 간주됩니다.

변환 생성자(converting constructor)는 인자의 타입들(있는 경우)에서 자신의 클래스 타입으로의 암시적 변환을 지정한다고 합니다. 비-explicit 사용자 정의 변환 함수 또한 암시적 변환을 지정합니다.

암시적으로 선언된(implicitly-declared) 그리고 사용자 정의(user-defined) 비명시적(non-explicit) 복사 생성자(copy constructors) 이동 생성자(move constructors) 는 변환 생성자(converting constructors)입니다.

예제

struct A
{
    A() { }         // 변환 생성자 (C++11부터)  
    A(int) { }      // 변환 생성자
    A(int, int) { } // 변환 생성자 (C++11부터)
};
struct B
{
    explicit B() { }
    explicit B(int) { }
    explicit B(int, int) { }
};
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 수행, 직접 초기화
//  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::B(int, int)
    B b5 = (B)1;   // OK: 명시적 캐스트가 static_cast 수행, 직접 초기화
    B b6;          // OK, 기본 초기화
    B b7{};        // OK, 직접 목록 초기화
//  B b8 = {};     // 오류: 복사 목록 초기화가 명시적 생성자 B::B()를 선택함
                   //        B::B()
    [](...){}(a1, a4, a4, a5, b5); // "사용되지 않은 변수" 경고를 억제할 수 있음
}

참고 항목