为什么初始化列表与表达式列表相比有不同的结果
Why does initializer-list have different result compared with expression-list
下面写代码的时候感觉很奇怪。我期待同样的输出,但事实证明是错误的。为什么这 2 个语句有不同的输出,(expression-list) 和 {initializer-list} 之间有什么区别?
cout << string(4, 'c') << endl;
cout << string{ 4, 'c' } << endl;
输出是:
cccc
c //a square '' before 'c'
两者都是constructor调用,但它们调用了两个不同的构造函数。第一次调用(link 中的“2”)构造了一个字符数,因此在你的情况下你得到 4 个“c”。
第二个构造函数(link 中的“9”)采用 std::initializer_list
。当您使用大括号而不是括号构造时,if class 有一个采用 initializer_list 的构造函数,它将始终优先。
如果有什么安慰的话,这种行为多年来一直困扰着很多程序员...
Otherwise, the constructors of T
are considered, in two phases:
All constructors that take std::initializer_list
as the only argument, or as the first argument if the remaining arguments have default values, are examined, and matched by overload resolution against a single argument of type std::initializer_list
If the previous stage does not produce a match, all constructors of T
participate in overload resolution against the set of arguments that consists of the elements of the braced-init-list, with the restriction that only non-narrowing conversions are allowed. If this stage produces an explicit constructor as the best match for a copy-list-initialization, compilation fails (note, in simple copy-initialization, explicit constructors are not considered at all).
你的情况
string(4, 'c')
使用以下构造函数。
std::string(size_type count,
char ch,
const Allocator& alloc = Allocator() );
另一方面,
string{ 4, 'c' }
使用以下构造函数。
std::string(std::initializer_list<char> ilist,
const Allocator& alloc = Allocator() );
如果 std::string
中没有定义第二个构造函数,那么这两个构造函数将生成相同的对象。
下面写代码的时候感觉很奇怪。我期待同样的输出,但事实证明是错误的。为什么这 2 个语句有不同的输出,(expression-list) 和 {initializer-list} 之间有什么区别?
cout << string(4, 'c') << endl;
cout << string{ 4, 'c' } << endl;
输出是:
cccc
c //a square '' before 'c'
两者都是constructor调用,但它们调用了两个不同的构造函数。第一次调用(link 中的“2”)构造了一个字符数,因此在你的情况下你得到 4 个“c”。
第二个构造函数(link 中的“9”)采用 std::initializer_list
。当您使用大括号而不是括号构造时,if class 有一个采用 initializer_list 的构造函数,它将始终优先。
如果有什么安慰的话,这种行为多年来一直困扰着很多程序员...
Otherwise, the constructors of
T
are considered, in two phases:
All constructors that take
std::initializer_list
as the only argument, or as the first argument if the remaining arguments have default values, are examined, and matched by overload resolution against a single argument of typestd::initializer_list
If the previous stage does not produce a match, all constructors of
T
participate in overload resolution against the set of arguments that consists of the elements of the braced-init-list, with the restriction that only non-narrowing conversions are allowed. If this stage produces an explicit constructor as the best match for a copy-list-initialization, compilation fails (note, in simple copy-initialization, explicit constructors are not considered at all).
你的情况
string(4, 'c')
使用以下构造函数。
std::string(size_type count,
char ch,
const Allocator& alloc = Allocator() );
另一方面,
string{ 4, 'c' }
使用以下构造函数。
std::string(std::initializer_list<char> ilist,
const Allocator& alloc = Allocator() );
如果 std::string
中没有定义第二个构造函数,那么这两个构造函数将生成相同的对象。