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 のような 明示的変換 を含む)でのみ考慮されるのに対し、変換コンストラクタは コピー初期化 でも考慮され、 ユーザー定義変換シーケンス の一部として機能します。

変換コンストラクタは、その引数の型(もしあれば)からそのクラスの型への暗黙変換を指定すると言われています。非明示的な ユーザー定義変換関数 も暗黙変換を指定することに注意してください。

暗黙的に宣言された、およびユーザー定義の非明示的 copy constructors および move 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 b5 = (B)1;   // OK: 明示的キャストはstatic_castを実行、直接初期化
    B b6;          // OK、デフォルト初期化
    B b7{};        // OK、直接リスト初期化
//  B b8 = {};     // エラー: コピーリスト初期化が明示的コンストラクタ
                   //        B::B() を選択した
    [](...){}(a1, a4, a4, a5, b5); // 「未使用変数」警告を抑制する可能性あり
}

関連項目