gpt4 book ai didi

c++ - 空括号调用默认构造函数还是采用 std::initializer_list 的构造函数?

转载 作者:可可西里 更新时间:2023-11-01 17:45:02 25 4
gpt4 key购买 nike

以下引自 Effective Modern C++(第 55 页):

"Suppose that you use an empty set of braces to construct an object that supports default constructor and also supports std::initializer_list construction. What do your empty braces mean? etc. The rule is that you get default construction."

我用 std::array 试过这个:

std::array<int, 10> arr{};

并收到来自 g++(版本 4.8.2)的警告:

warning: missing initializer for member ‘std::array<int, 10ul>::_M_elems’

这是尝试从空的 std::initializer_list 构造 std::array 时得到的警告(有关此警告的讨论,请参见 Why can I initialize a regular array from {}, but not a std::array ).

那么,为什么上面的代码行没有被解释为调用默认构造函数呢?

最佳答案

那是因为std::array是一个聚合,因此 aggregate initialization draft C++11 standard 中对此进行了介绍8.5.4 [dcl.init.list] 部分说:

List-initialization of an object or reference of type T is defined as follows:

  • If the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.

  • Otherwise, if T is an aggregate, aggregate initialization is performed (8.5.1).

    double ad[] = { 1, 2.0 }; // OK
    int ai[] = { 1, 2.0 }; // error: narrowing

    struct S2 {
    int m1;
    double m2, m3;
    };

    S2 s21 = { 1, 2, 3.0 }; // OK
    S2 s22 { 1.0, 2, 3 }; // error: narrowing
    S2 s23 { }; // OK: default to 0,0,0

我们可以看看它是否不是一个聚合然后列表继续说:

  • Otherwise, if T is a specialization of std::initializer_list, an initializer_list object is constructed as described below and used to initialize the object according to the rules for initialization of an object from a class of the same type (8.5).
  • Otherwise, if T is a class type, constructors are considered. The applicable constructors are enumerated and the best one is chosen through overload resolution (13.3, 13.3.1.7). If a narrowing conversion (see below) is required to convert any of the arguments, the program is ill-formed.

我们可以确认 std::array23.3.2.1 部分的聚合 [array.overview]:

An array is an aggregate (8.5.1) that can be initialized with the syntax

array<T, N> a = { initializer-list };

where initializer-list is a comma-separated list of up to N elements whose types are convertible to T.

部分 8.5.1 引用的是 8.5.1 聚合 [dcl.init.aggr] 并说:

When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer list are taken as initializers for the members of the aggregate, in increasing subscript or member order [...]

然后我们绕了一圈回到 8.5.4 部分,这是我们开始的地方。

关于c++ - 空括号调用默认构造函数还是采用 std::initializer_list 的构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31278377/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com