C++11:列表初始化中的 () 或 {}?
C++11: () or {} in List-initialization?
我指的是“The working draft N3337", which is said most similar to the published C++11 standard。
如果有匹配的构造函数,则调用构造函数。
Example (p200):
struct S {
// no initializer-list constructors
S(int, double, double); // #1
S(); // #2
// ...
};
S s1 = { 1, 2, 3.0 }; // OK: invoke #1
S s2 { 1.0, 2, 3 }; // error: narrowing
否则,将使用聚合初始化。
现在,here 是一个使用 vector
的示例,它有一个来自 size_t
的显式构造函数和一个 initializer_list
构造函数:
vector<double> v1(7); // ok: v1 has 7 elements
vector<double> v1{7}; // ok: v1 has 1 element (with its value 7.0)
在这里我很困惑。为什么 vector
构造函数的行为与 S
构造函数的行为不同?
因为 initializer_list
重载强烈优于所有其他重载。来自 [over.match.list]:
When objects of non-aggregate class type T
are list-initialized (8.5.4), overload resolution selects the constructor
in two phases:
(1.1) — Initially, the candidate functions are the initializer-list constructors (8.5.4) of the class T
and the
argument list consists of the initializer list as a single argument.
(1.2) — If no viable initializer-list constructor is found, overload resolution is performed again, where the
candidate functions are all the constructors of the class T
and the argument list consists of the elements
of the initializer list.
vector
是一个非聚合 [=26=],它有两个相关的构造函数:
explicit vector( size_type count ); // (3)
vector( std::initializer_list<T> init, // (7)
const Allocator& alloc = Allocator() );
根据 [over.match.best] 中描述的顺序,由于 (7) 是一个可行的构造函数候选者,我们不会指出 (1.2) 其中 (3) 会被考虑。
我指的是“The working draft N3337", which is said most similar to the published C++11 standard。
如果有匹配的构造函数,则调用构造函数。
Example (p200):
struct S {
// no initializer-list constructors
S(int, double, double); // #1
S(); // #2
// ...
};
S s1 = { 1, 2, 3.0 }; // OK: invoke #1
S s2 { 1.0, 2, 3 }; // error: narrowing
否则,将使用聚合初始化。
现在,here 是一个使用 vector
的示例,它有一个来自 size_t
的显式构造函数和一个 initializer_list
构造函数:
vector<double> v1(7); // ok: v1 has 7 elements
vector<double> v1{7}; // ok: v1 has 1 element (with its value 7.0)
在这里我很困惑。为什么 vector
构造函数的行为与 S
构造函数的行为不同?
因为 initializer_list
重载强烈优于所有其他重载。来自 [over.match.list]:
When objects of non-aggregate class type
T
are list-initialized (8.5.4), overload resolution selects the constructor in two phases:(1.1) — Initially, the candidate functions are the initializer-list constructors (8.5.4) of the class
T
and the argument list consists of the initializer list as a single argument.
(1.2) — If no viable initializer-list constructor is found, overload resolution is performed again, where the candidate functions are all the constructors of the classT
and the argument list consists of the elements of the initializer list.
vector
是一个非聚合 [=26=],它有两个相关的构造函数:
explicit vector( size_type count ); // (3)
vector( std::initializer_list<T> init, // (7)
const Allocator& alloc = Allocator() );
根据 [over.match.best] 中描述的顺序,由于 (7) 是一个可行的构造函数候选者,我们不会指出 (1.2) 其中 (3) 会被考虑。