c – 在gcc 4.8中初始化静态constexpr成员数组

使用-std = c 11时,以下代码gcc 4.9.1和clang-3.6中编译和运行:
struct Bar
{
    int x;
};

struct Foo
{
    static constexpr Bar bars[] = {1,2,3};
};

constexpr Bar Foo::bars[];

但是,它在gcc 4.8.3中失败,导致错误消息

./cpptest.cpp:14:43: error: Could not convert '1' from 'int' to 'const Bar'
     static constexpr Bar bars[] = {1,3};
                                           ^
./cpptest.cpp:14:43: error: Could not convert '2' from 'int' to 'const Bar'
./cpptest.cpp:14:43: error: Could not convert '3' from 'int' to 'const Bar'

顺便说一下,如果我做同样的事情,但使条形成一个静态的const全局数组,它在gcc 4.8和clang中编译得很好.如果我用一对额外的{}包围列表中的每个整数文字,它也会编译得很好.

这是gcc 4.8中的一个错误吗?标准所说的是适当的语法?当我省略额外的括号时,调用了c 11统一初始化标准的哪一部分?

编辑:看起来标准说这应该调用聚合初始化,这应该允许“支持elision”.所以它似乎是gcc 4.8中的一个错误,这是由gcc 4.9修复的,但我对阅读标准并不是很有信心.我也似乎无法在gcc的bug追踪器中发现任何有关此问题的错误报告,所以我很容易出错.

解决方法

为了做你想做的事,你需要在Foo中指定一个constexpr构造函数
struct Bar
{
    constexpr Bar(int c) : x(c)
    {}

    int x;
};

struct Foo
{
    static constexpr Bar bars[] = {1,3};
};

constexpr Bar Foo::bars[];

显然,gcc 4.8.3并不会将花括号内的值转换为Bar对象,而gcc 4.9.1则可以.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...