c++ - g++ (4.7.2) 错误或功能,在编译时初始化静态数组时?

标签 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,从 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;
};

最佳答案

以下是非法的;

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

所以gcc的bug其实是针对非模板的情况。

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

关于c++ - g++ (4.7.2) 错误或功能,在编译时初始化静态数组时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21435431/

相关文章:

c++ - 返回一个打开的套接字连接/保留一个打开的套接字连接 C++

javascript - 将数组中的对象映射到单个对象的最佳方法

c - 从字符数组进行浮点检查以进行限制,字符检查正面和背面

c++ - 处理指向模板中成员的指针,同时创建更简单的 `bind` 以与 asio 一起使用

c++ - 是否值得添加一个支持 move 的二传手?

c++ - 指针作为多重映射中的键

javascript - 如何使用 JavaScript 在 HTML DOM 对象数组中通过数据选择器查找元素?

C++ 模板可变参数函数 undefined reference

' ' : free(): invalid pointer 中的 C++ 错误

c++ - 为什么我的析构函数没有被调用?