Итак, я пытался сделать что-то умное, инициализируя кучу 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, где значение каждого последующего элемента определяется функтором Template-Metaprogramming, называемым Increment
(Т.е. {0, 1, ..., 9}
). Как и ожидалось, программа распечатывает номер 3
,
Круто, верно? Теперь я могу просто написать функторы и инициализировать массивы различными типами паттернов во время компиляции. Следующий шаг: отмените жесткий код размера массива 10, сделав Test
шаблон класса так:
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 на самом деле не для случая шаблона.
Вы можете использовать std::array
вместо C-массива.
Других решений пока нет …