g++(4.7.2)错误或特性,在编译时初始化静态数组时
g++ (4.7.2) bug or feature, when initializing static arrays at compile-time?
好吧,所以我试图通过在编译时初始化一堆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
的实现)。就目前而言,我认为这已经足够了。
EDIT可以使用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阵列。
相关文章:
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 为什么通过指针编译时不能分配 const 初始化
- 使用直接大括号初始化时,C++ 编译错误"声明末尾的预期";"
- 是否可以在编译时初始化对象的 C 样式函数指针,以便它调用对象的成员函数?
- c++ 是否保证标头初始化的静态 const 成员跨编译单元和库共享单个实例?
- (C++)我的自定义数组无法初始化(编译错误)
- 返回语句中矢量初始化时出现编译错误
- 如何实现使用 gcc-4.4 编译的大向量初始化?
- 为什么在直接初始化和赋值中传递 lambda 而不是在复制初始化中传递 lambda 时会编译?
- 这是通过初始化 constexpr 变量来标记编译错误的合理跳转
- 使用全局变量初始化不同编译单元中的其他全局变量
- 尝试初始化结构向量时出现编译错误
- 初始化不可移动对象数组:为什么这样的代码无法在 GCC 上编译?
- 模板,从编译时初始化器列表中的数组分支为长度分支
- 为什么 GCC 6.3 在没有显式 C++11 支持的情况下编译此大括号初始化列表代码
- C++ 编译时检查微控制器引脚是否已从其他源文件初始化
- 编译时收到未初始化的内存警告
- C++编译错误(在此函数中未初始化)
- Visual Studio 编译的程序在尝试减小输出大小后无法正确初始化
- C++14 元编程:在编译/初始化时自动构建类型列表