这个列表里,哪个长尾词能填满空空如也的大括号?

2026-04-02 00:541阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计702个文字,预计阅读时间需要3分钟。

这个列表里,哪个长尾词能填满空空如也的大括号?

考虑以下最小示例:

尝试以下示例:

考虑以下最小示例:#includeiostreamstructX{X(){std::coutD

考虑以下最小示例:

#include struct X { X() { std::cout <<"Default-ctor" <Godbolt 示例

我对 a、b 和 c 没有任何疑问,一切都很清楚

但我不明白为什么 d 有效

d 中这对额外的大括号代表什么?我查了 C++20 标准,但我找不到答案。clang 和 gcc 都同意这个代码,所以我错过了一些东西

回答

获取有关编译器功能的信息的一个很好的技巧是使用所有错误进行编译: -Weverything. 让我们看看这里的输出(d仅适用于):

9.cpp:16:6: warning: constructor call from initializer list is incompatible with C++98 [-Wc++98-compat] X d{{{}}}; // reads as construct from what? ^~~~~~

X::X(std::initializer_list) 叫做。

9.cpp:16:8: warning: scalar initialized from empty initializer list is incompatible with C++98 [-Wc++98-compat] X d{{{}}}; // reads as construct from what? ^~

标量 ( int) 在内部初始化{}。所以我们有X d{{0}}.

9.cpp:16:7: warning: initialization of initializer_list object is incompatible with C++98 [-Wc++98-compat] X d{{{}}}; // reads as construct from what? ^~~~ 5 warnings generated.

std::initializer_list从 初始化{0}。所以我们有X d{std::initializer_list{0}};!

这向我们展示了我们需要的一切。额外的括号用于构造初始化列表。

注意:如果您想添加额外的括号,您可以调用复制/移动构造函数(或省略它),但 C++ 编译器不会为您隐式地执行此操作以防止错误:

X d{X{{{}}}}; // OKX e{{{{}}}}; // ERROR


    以为我只是说明:

    X d{ { {} }}; | | | construct an | | `X` from ... an initializer_list | containing... int{}

    列表初始化的规则是找到一个initializer_list构造函数并在可能的情况下使用它,否则......枚举构造函数并做正常的事情。

    这个列表里,哪个长尾词能填满空空如也的大括号?

    使用X{{}},即列表初始化:最外面的{}s 是initializer_list并且 this 包含一个元素:{},即0。足够直截了当(虽然神秘)。

    但是对于X{{{}}},这不再使用最外层{}作为 the ,initializer_list因为您无法初始化intfrom {{}}。所以我们回退到使用构造函数。现在,其中一个构造函数需要一个initializer_list,所以这有点像重新开始,只是我们已经剥掉了一层大括号。


    这就是为什么例如也vector{{1, 2, 3}}可以工作,而不仅仅是vector{1, 2, 3}. 但就像……不要。


      本文共计702个文字,预计阅读时间需要3分钟。

      这个列表里,哪个长尾词能填满空空如也的大括号?

      考虑以下最小示例:

      尝试以下示例:

      考虑以下最小示例:#includeiostreamstructX{X(){std::coutD

      考虑以下最小示例:

      #include struct X { X() { std::cout <<"Default-ctor" <Godbolt 示例

      我对 a、b 和 c 没有任何疑问,一切都很清楚

      但我不明白为什么 d 有效

      d 中这对额外的大括号代表什么?我查了 C++20 标准,但我找不到答案。clang 和 gcc 都同意这个代码,所以我错过了一些东西

      回答

      获取有关编译器功能的信息的一个很好的技巧是使用所有错误进行编译: -Weverything. 让我们看看这里的输出(d仅适用于):

      9.cpp:16:6: warning: constructor call from initializer list is incompatible with C++98 [-Wc++98-compat] X d{{{}}}; // reads as construct from what? ^~~~~~

      X::X(std::initializer_list) 叫做。

      9.cpp:16:8: warning: scalar initialized from empty initializer list is incompatible with C++98 [-Wc++98-compat] X d{{{}}}; // reads as construct from what? ^~

      标量 ( int) 在内部初始化{}。所以我们有X d{{0}}.

      9.cpp:16:7: warning: initialization of initializer_list object is incompatible with C++98 [-Wc++98-compat] X d{{{}}}; // reads as construct from what? ^~~~ 5 warnings generated.

      std::initializer_list从 初始化{0}。所以我们有X d{std::initializer_list{0}};!

      这向我们展示了我们需要的一切。额外的括号用于构造初始化列表。

      注意:如果您想添加额外的括号,您可以调用复制/移动构造函数(或省略它),但 C++ 编译器不会为您隐式地执行此操作以防止错误:

      X d{X{{{}}}}; // OKX e{{{{}}}}; // ERROR


        以为我只是说明:

        X d{ { {} }}; | | | construct an | | `X` from ... an initializer_list | containing... int{}

        列表初始化的规则是找到一个initializer_list构造函数并在可能的情况下使用它,否则......枚举构造函数并做正常的事情。

        这个列表里,哪个长尾词能填满空空如也的大括号?

        使用X{{}},即列表初始化:最外面的{}s 是initializer_list并且 this 包含一个元素:{},即0。足够直截了当(虽然神秘)。

        但是对于X{{{}}},这不再使用最外层{}作为 the ,initializer_list因为您无法初始化intfrom {{}}。所以我们回退到使用构造函数。现在,其中一个构造函数需要一个initializer_list,所以这有点像重新开始,只是我们已经剥掉了一层大括号。


        这就是为什么例如也vector{{1, 2, 3}}可以工作,而不仅仅是vector{1, 2, 3}. 但就像……不要。