g++ 4.9 拒绝 C++14 中的有效聚合初始化

2022-01-23 00:00:00 g++ c++ c++14

考虑这段代码:

struct S
{
    int x;
    double y = 1.1;
};

int main()
{
    S s = {0};
}

根据 C++14 标准,§ 8.5.1/7

According to the C++14 standard, § 8.5.1/7

如果列表中的初始化子句少于聚合中的成员,则每个未显式初始化的成员都应从其大括号或相等初始化器中初始化,或者,如果没有大括号或相等- 初始化器,来自一个空的初始化器列表 (8.5.4).

If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member not explicitly initialized shall be initialized from its brace-or-equal-initializer or, if there is no brace-or-equal- initializer, from an empty initializer list (8.5.4).

代码应该完全有效.

但是,g++ 4.9.2 拒绝该代码(使用 -std=c++14 编译)

However, g++ 4.9.2 rejects the code (compiled with -std=c++14)

so.cpp:9:13: error: could not convert '{0}' from '<brace-enclosed initializer list>' to 'S'
     S s = {0};

clang++ 另一方面编译它.

clang++ on the other hand compiles it.

这是 g++ 的已知问题吗?

Is this a known issue for g++?

推荐答案

你是对的,这是有效的 C++14;但是,在 C++11 中,在类成员初始化器中的类不是聚合,因此这在 C 中无效++11.

You are correct, this is valid C++14; however, in C++11 a class with in class member initializers was not an aggregate and so this is not valid in C++11.

我在回答上述问题时指出的问题是,在我发表初步评论后我后来意识到 gcc 直到 5.0 才支持此更改(见它活着):

The issue as I noted in my answer to the above question and I realized later after I made my initial comment is that gcc did not support this change until 5.0 (see it live):

G++ 现在支持具有非静态数据成员的 C++14 聚合初始化器.

G++ now supports C++14 aggregates with non-static data member initializers.

struct A { int i, j = i; };
A a = { 42 }; // a.j is also 42

相关文章