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) 的构造函数被称为 转换构造函数

与仅在 直接初始化 (包括如 static_cast 显式转换 )过程中被考虑的显式构造函数不同,转换构造函数还会在 拷贝初始化 过程中被考虑,作为 用户定义转换序列 的一部分。

据说转换构造函数指定了从其参数类型(如果有)到其类类型的隐式转换。请注意,非显式的 用户定义转换函数 同样指定了隐式转换。

隐式声明和用户定义的非显式 复制构造函数 移动构造函数 均为转换构造函数。

示例

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;      // 正确:复制初始化选择 A::A(int)
    A a2(2);       // 正确:直接初始化选择 A::A(int)
    A a3{4, 5};    // 正确:直接列表初始化选择 A::A(int, int)
    A a4 = {4, 5}; // 正确:复制列表初始化选择 A::A(int, int)
    A a5 = (A)1;   // 正确:显式转换执行 static_cast,直接初始化
//  B b1 = 1;      // 错误:复制初始化不考虑 B::B(int)
    B b2(2);       // 正确:直接初始化选择 B::B(int)
    B b3{4, 5};    // 正确:直接列表初始化选择 B::B(int, int)
//  B b4 = {4, 5}; // 错误:复制列表初始化选择了显式构造函数
                   //        B::B(int, int)
    B b5 = (B)1;   // 正确:显式转换执行 static_cast,直接初始化
    B b6;          // 正确,默认初始化
    B b7{};        // 正确,直接列表初始化
//  B b8 = {};     // 错误:复制列表初始化选择了显式构造函数
                   //        B::B()
    [](...){}(a1, a4, a4, a5, b5); // 可能抑制“未使用变量”警告
}

参见