【问题标题】:Why does Clang 12 refuse to initialize aggregates in the C++20 way?为什么 Clang 12 拒绝以 C++20 的方式初始化聚合?
【发布时间】:2021-09-01 12:28:32
【问题描述】:

据我了解,以下程序应该可以在 C++20 模式下运行:

#include <vector>

struct B{ int a0, a1; };

int main()
{
    std::vector<B> bs;
    bs.emplace_back( 0, 0 );
}

在 Visual Studio 2019 和 gcc 11 中确实如此。但在产生错误的 clang 12 中却没有:

/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/12.0.0/../../../../include/c++/12.0.0/bits/alloc_traits.h:514:4: error: no matching function for call to 'construct_at'
          std::construct_at(__p, std::forward<_Args>(__args)...);
          ^~~~~~~~~~~~~~~~~

在线编译器中:https://gcc.godbolt.org/z/GzccTWc5z

这是因为 clang 还不完全支持 C++20 吗?

【问题讨论】:

    标签: c++ clang c++20 emplace aggregate-initialization


    【解决方案1】:

    这是一个 C++20 特性,允许通过标准构造函数语法进行聚合初始化,而不是典型的花括号列表初始化语法。 (请注意,这仅在参数不能用于对默认构造函数或复制/移动构造函数的有效调用时才有效。如果可以,将调用它而不是执行聚合初始化。)

    根据官方C++ Support in Clang 页面,Clang 还不支持带括号的聚合初始化(即P0960R3P1975R0)。这是 Clang 版本 13 的版本。

    还维护了 C++20 功能的支持矩阵 on cppreference.com。由此可见对P0960R3的支持如下:

    • GCC:从版本 10 开始支持
    • MSVC:从 19.28 版开始支持
    • EDG eccp:从 5.1 版开始支持
    • Clang 和 Apple Clang:不支持
    • 英特尔 ICC:不支持

    【讨论】:

    • “请注意,这仅在参数不能用于对默认构造函数或复制/移动构造函数的有效调用时才有效。如果可以,将调用它而不是执行聚合初始化。”。至少这与行为方式与 AFAIK 相同的大括号初始化一致。或者这里有什么不同?想到一件事:我怀疑如果初始化程序隐式转换为聚合类型,事情可能会有所不同。
    猜你喜欢
    • 2021-10-03
    • 2015-03-22
    • 2023-03-10
    • 2010-10-02
    • 1970-01-01
    • 2022-01-04
    • 2017-07-01
    • 1970-01-01
    相关资源
    最近更新 更多