C++ 初始化列表和默认值

C++ initializer list and default values

此代码是否适用于 C++14

using namespace std;
struct Point
{
  int x = 0;
  int y = 0;
};
Point p2 {1, 1};

它在 clang++ 7.0 上编译得很好,在这两种情况下都不适用于 G++ 4.9 我将 --std=c++1y 传递给编译器。

在 G++ 中,当我从结构定义中删除默认值时它会起作用。

g++ test_constexpr_ctor.cc --std=c++1y -o test
test_constexpr_ctor.cc:7:15: error: no matching function for call to ‘Point::Point(<brace-enclosed initializer list>)’
Point p2 {1, 1};
            ^
test_constexpr_ctor.cc:7:15: note: candidates are:
test_constexpr_ctor.cc:1:8: note: constexpr Point::Point()
struct Point
        ^
test_constexpr_ctor.cc:1:8: note:   candidate expects 0 arguments, 2 provided
test_constexpr_ctor.cc:1:8: note: constexpr Point::Point(const Point&)
test_constexpr_ctor.cc:1:8: note:   candidate expects 1 argument, 2 provided
test_constexpr_ctor.cc:1:8: note: constexpr Point::Point(Point&&)
test_constexpr_ctor.cc:1:8: note:   candidate expects 1 argument, 2 provided

代码有效。

  1. (8.5.4/3):

List-initialization of an object or reference of type T is defined as follows: — If T is an aggregate, aggregate initialization is performed

  1. c++14 中的聚合定义为 (8.5.1/1):

An aggregate is an array or a class (Clause 9 ) with no user-provided constructors ( 12.1 ), no private or protected non-static data members (Clause 11 ), no base classes (Clause 10 ), and no virtual functions ( 10.3 ).

请注意,在 c++11 中,此定义看起来有所不同(重点是我的):

An aggregate is an array or a class (Clause 9 ) with no user-provided constructors ( 12.1 ), no brace-or-equal- initializer s for non-static data members ( 9.2 ), no private or protected non-static data members (Clause 11 ), no base classes (Clause 10 ), and no virtual functions ( 10.3 ).

由于这部分在c++14中被移除,你的结构肯定是一个聚合,因此应该进行聚合初始化。

这是 gcc5 中的 fixed(在更改列表中搜索 "aggregates with non-static data member initializers")。不过,我不会将其称为 "bug",而是 gcc 团队仅在 gcc 5.1.0 中实现了该更改。

您发布的代码完全正确。

但是您的行为是 not yet closed bug of G++ version 4.9.1. Actually, it may be a duplicate and closed in some other bug report, because the problem is fixed since g++ 5.1.0 or maybe even earlier version. To find actual bug you may use bugzilla's search