使用空的初始化程序列表直接进行初始化 [英] Direct initialization with empty initializer list

查看:170
本文介绍了使用空的初始化程序列表直接进行初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

struct X
{
    X() { std::cout << "default ctor" << std::endl; }

};

int main()
{
    X({});
}

这将打印出来

default ctor

这是有道理的,因为空括号值会初始化对象(我认为). 但是,

and that makes sense because empty brace value-initializes the object (I think). However,

struct X
{
    X() { std::cout << "default ctor" << std::endl; }
    X(std::initializer_list<int>) { std::cout << "initializer list" << std::endl; }
};

int main()
{
    X({});
}

为此,我得到了

initializer list

我觉得这种行为并不奇怪,但我并不完全相信.这有什么规则?

I don't find this behavior so strange, but I'm not fully convinced. What is the rule for this?

此行为是否写在标准的某些部分中?

Is this behavior written in some part of the standard?

推荐答案

此行为是否写在标准的某些部分中?

Is this behavior written in some part of the standard?

当然.这完全由 [dcl.init]/16 中的规则决定>,重点要与您的初始化程序匹配:

Of course. It's all dictated by the rules in [dcl.init]/16, emphasis mine to match your initializer:

初始化器的语义如下.目标类型是 初始化的对象或引用的类型以及源 type是初始化表达式的类型.如果初始化器是 不是单个(可能用括号括起来的)表达式,源类型是 未定义.

The semantics of initializers are as follows. The destination type is the type of the object or reference being initialized and the source type is the type of the initializer expression. If the initializer is not a single (possibly parenthesized) expression, the source type is not defined.

  • 如果初始化程序是一个(非括号)括号初始化列表,则该对象或引用将进行列表初始化([dcl.init.list]).

  • If the initializer is a (non-parenthesized) braced-init-list, the object or reference is list-initialized ([dcl.init.list]).

[...]

如果目标类型是(可能是cv限定的)类类型:

If the destination type is a (possibly cv-qualified) class type:

  • 如果初始化是直接初始化,或者是复制初始化,则源的cv不合格版本 type是与该类相同的类,或者是该类的派生类 目的地,则考虑构造函数.适用的构造函数 枚举([over.match.ctor]),然后通过选择最佳的 重载分辨率([over.match]).这样选择的构造函数是 通过初始化器表达式调用,以初始化对象 expression-list作为其参数.如果没有构造函数适用,或者 重载解决方案模棱两可,初始化格式错误.
  • [...]
  • If the initialization is direct-initialization, or if it is copy-initialization where the cv-unqualified version of the source type is the same class as, or a derived class of, the class of the destination, constructors are considered. The applicable constructors are enumerated ([over.match.ctor]), and the best one is chosen through overload resolution ([over.match]). The constructor so selected is called to initialize the object, with the initializer expression or expression-list as its argument(s). If no constructor applies, or the overload resolution is ambiguous, the initialization is ill-formed.
  • [...]

您提供了一个带括号的空括号初始化列表,因此仅适用于后面的项目符号.考虑构造函数,在第一种情况下,我们最终从默认的初始化X进行了复制初始化.在后一种情况下,选择initializer_list c'tor作为更好的匹配. [over.ics.list] <中指定了选择此重载的规则. /a>:

You supply a parenthesized empty brace-init-list, so only the later bullet applies. Constructors are considered, and in the first case we end up doing a copy-initialization from a default initialized X. In the latter case, the initializer_list c'tor is chosen as a better match. The rule for choosing this overload is specified in [over.ics.list]:

当参数是初始值设定项列表([dcl.init.list])时,则不是 表达式和特殊规则适用于将其转换为参数 类型.

When an argument is an initializer list ([dcl.init.list]), it is not an expression and special rules apply for converting it to a parameter type.

如果参数类型为std :: initializer_list或"X的数组",并且 初始化列表的所有元素都可以隐式转换 到X,隐式转换顺序是最差的转换 将列表中的元素转换为X所必需的.这种转换可以 即使在调用的上下文中也是用户定义的转化 初始化程序列表构造函数.

If the parameter type is std::initializer_list or "array of X" and all the elements of the initializer list can be implicitly converted to X, the implicit conversion sequence is the worst conversion necessary to convert an element of the list to X. This conversion can be a user-defined conversion even in the context of a call to an initializer-list constructor.

否则,如果参数是非聚合类X并且重载 每个[over.match.list]的分辨率选择一个最佳的构造函数 X可以从X中执行类型为X的对象的初始化 参数初始值设定项列表,隐式转换序列为 用户定义的转换顺序.如果多个构造函数可行 但是没有一个比其他的更好,隐式转换顺序 是不明确的转换顺序.用户定义的转换是 允许将初始值设定项列表元素转换为 构造函数参数类型,除非[over.best.ics]中有说明.

Otherwise, if the parameter is a non-aggregate class X and overload resolution per [over.match.list] chooses a single best constructor of X to perform the initialization of an object of type X from the argument initializer list, the implicit conversion sequence is a user-defined conversion sequence. If multiple constructors are viable but none is better than the others, the implicit conversion sequence is the ambiguous conversion sequence. User-defined conversions are allowed for conversion of the initializer list elements to the constructor parameter types except as noted in [over.best.ics].

这篇关于使用空的初始化程序列表直接进行初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆