直接初始化中的转换运算符
Conversion operator in direct-initialization
C++14 标准 (N4296) 在 8.5/17.6.1
中说
If the initialization is direct-initialization [...], constructors are considered. The applicable constructors are enumerated, and the best
one is chosen through overload resolution. [...] If no constructor
applies, or the overload resolution is ambiguous, the initialization is ill-formed.
因此在直接初始化中,只考虑构造函数——忽略转换函数。在下面的代码中没有 A
的适用构造函数,只有 B
的转换函数。但是,代码编译通过,为什么?
struct A{};
struct B{
operator A(){ return A{}; }
};
int main() {
B b;
A a(b); // direct-initialization
}
您是正确的,在执行 A a(b);
时只考虑 A
的构造函数。 [over.match.ctor]/1 个州
When objects of class type are direct-initialized, copy-initialized from an expression of the same or a derived class type ([dcl.init]), or default-initialized, overload resolution selects the constructor. For direct-initialization or default-initialization that is not in the context of copy-initialization, the candidate functions are all the constructors of the class of the object being initialized. For copy-initialization (including default initialization in the context of copy-initialization), the candidate functions are all the converting constructors ([class.conv.ctor]) of that class. The argument list is the expression-list or assignment-expression of the initializer.
强调我的
这意味着A()
、A(const A&)
和A(A&&)
是候选列表。然后我们有 [over.match.viable]/4
[...]Third, for F to be a viable function, there shall exist for each argument an implicit conversion sequence that converts that argument to the corresponding parameter of F.[..]
允许将 b
隐式转换为 A
,以便可以调用 A(A&&)
。
C++14 标准 (N4296) 在 8.5/17.6.1
中说If the initialization is direct-initialization [...], constructors are considered. The applicable constructors are enumerated, and the best one is chosen through overload resolution. [...] If no constructor applies, or the overload resolution is ambiguous, the initialization is ill-formed.
因此在直接初始化中,只考虑构造函数——忽略转换函数。在下面的代码中没有 A
的适用构造函数,只有 B
的转换函数。但是,代码编译通过,为什么?
struct A{};
struct B{
operator A(){ return A{}; }
};
int main() {
B b;
A a(b); // direct-initialization
}
您是正确的,在执行 A a(b);
时只考虑 A
的构造函数。 [over.match.ctor]/1 个州
When objects of class type are direct-initialized, copy-initialized from an expression of the same or a derived class type ([dcl.init]), or default-initialized, overload resolution selects the constructor. For direct-initialization or default-initialization that is not in the context of copy-initialization, the candidate functions are all the constructors of the class of the object being initialized. For copy-initialization (including default initialization in the context of copy-initialization), the candidate functions are all the converting constructors ([class.conv.ctor]) of that class. The argument list is the expression-list or assignment-expression of the initializer.
强调我的
这意味着A()
、A(const A&)
和A(A&&)
是候选列表。然后我们有 [over.match.viable]/4
[...]Third, for F to be a viable function, there shall exist for each argument an implicit conversion sequence that converts that argument to the corresponding parameter of F.[..]
允许将 b
隐式转换为 A
,以便可以调用 A(A&&)
。