首先,C++语法规则使尾随,
可选,用于括号初始化列表。引用dcl.init/1
声明者可以为标识为 的声明指定初始值。标识符指定正在初始化的变量。在[dcl.init] 的其余部分中描述的初始化过程也适用于由其他语法上下文指定的初始化,例如函数参数初始化([expr.call])或返回值初始化([ stmt.return])。
initializer:
brace-or-equal-initializer
(expression-list)
brace-or-equal-initializer:
= initializer-clause
braced-init-list
initializer-clause:
assignment-expression
braced-init-list
braced-init-list:
{ initializer-list ,opt }
{ designated-initializer-list ,opt }
{ }
其次,你不能几乎覆盖重载解析系统。如果使用这种语法,它将始终使用std::initializer_list
构造函数,并且此类构造函数可用。
dcl.init.list/2:
构造函数是一个初始化列表构造如果它的第一个参数 是类型为std :: initializer_list或参照 可能CV-合格的std :: initializer_list对于一些键入E,并且 要么没有其他参数,要么所有其他参数都具有默认参数 。 [注意:初始化列表构造函数比list-initialization([over.match.list])中的其他构造函数更受青睐....
下面打印Using InitList
程序:
#include <iostream>
#include <initializer_list>
struct X{
X(std::initializer_list<double>){ std::cout << "Using InitList\n"; }
X(int){ std::cout << "Using Single Arg ctor\n"; }
};
int main(){
X x{5};
}
尽管5
是文字int
型的,它应该是有意义的选择,因为它是一个单参数的构造函数完美搭配;并且std::initializer_list<double>
构造函数想要一个double
的列表。但是,规则有利于std::initializer_list<double>
,因为它的初始值设定项列表构造函数。
其结果是,即使下面的程序将失败,因为收缩转换:
#include <iostream>
#include <initializer_list>
struct Y{
Y(std::initializer_list<char>){ std::cout << "Y Using InitList\n"; }
Y(int, int=4){ std::cout << "Y Using Double Arg ctor\n"; }
};
int main(){
Y y1{4777};
Y y2{577,};
Y y3{57,7777};
}
在回答下面的评论,“如果有一种是的std :: initializer_list没有超载,或它不是第一个构造函数的参数?“ - 然后重载解析不会选择它。演示:
#include <iostream>
#include <initializer_list>
struct Y{
Y(int, std::initializer_list<double>){ std::cout << "Y Using InitList\n"; }
Y(int, int=4){ std::cout << "Y Using Double Arg ctor\n"; }
};
int main(){
Y y1{4};
Y y2{5,};
Y y3{5,7};
}
打印:
Y Using Double Arg ctor
Y Using Double Arg ctor
Y Using Double Arg ctor
如果没有初始化列表构造可用,那么{initializer-list...,}
初始化几乎回落到直接初始化按dcl.init/16,其语义包含在前面的段落dcl.init/16
第一个('std :: initializer_list'-constructor)总是s当选。 https://wandbox.org/permlink/Yy6VtcK5ISCbzZJp – songyuanyao
无论如何,没有理由'v2 {...}'调用任何构造函数,但只有'std :: initializer_list' ....只有'v2(。 ..)'会调用'std :: vector :: vector(std :: size_t ...)' – jpo38
@songyuanyao是的,但如果只有构造函数具有一元和二元的arities,可能的,默认的函数参数初始值设定项和其他情况?在所有可想象的情况下,有没有*语义差异? – Orient