g ++(4.7.2)错误或特性,在编译时初始化静态数组?

时间:2014-01-29 15:28:46

标签: c++ arrays templates initialization compiler-bug

好的,所以我试图通过在编译时初始化一堆constexpr static int const数组来做一些聪明的事情。尽管运行时性能完全不是通过初始化这些数组来控制的,但它似乎是一个有趣的小练习。我写了一个测试设置,看看是否可能,我最终能够做到这一点:

struct Test
{
    constexpr static int const array[10] = Array<int, 10, 0, Increment>::array;
};

constexpr int const Test::array[10];

int main()
{
    cout << Test::array[3] << '\n';
}

此处,Array有一个名为array的静态成员,其中包含10个int s,从0开始,其中每个后续元素的值由名为的模板 - 元编程函数函数确定Increment(即{0, 1, ..., 9})。正如预期的那样,该程序打印出数字3

太棒了吧?我现在可以编写仿函数,并在编译时初始化数组将各种时髦的模式。下一步:通过使Test像这样的类模板对数组大小10进行非硬编码:

template <size_t Size>
struct Test
{
    constexpr static int const array[Size] = Array<int, Size, 0, Increment>::array;
};

template <size_t Size>
constexpr int const Test<Size>::array[Size];

int main()
{
    cout << Test<10>::array[3] << '\n';
}

然而,突然间它不再编译了消息:

test.cc:43:72: error: array must be initialized with a brace-enclosed initializer

为什么会这样?有没有理由说这种初始化在我将类转换为类模板后变得无效,或者我偶然发现了GCC中未实现/错误的东西?

仅供参考,我可以根据请求发布我的其余代码(例如Array的实现)。现在我认为这应该足够了。

编辑错误可以通过Array的不同,琐碎的实现来重现,以节省一些空间:

template <size_t Size>
struct Array
{
    constexpr static int const array[Size] = {};
};

template <size_t Size>
struct Test
{
    constexpr static int const array[Size] = Array<Size>::array;
};

1 个答案:

答案 0 :(得分:4)

以下是非法的;

static const int a[10] = {};
static const int b[10] = a; // Illegal

因此,gcc的错误实际上是非模板案例。

您可以使用std::array代替C-array。