Инициализация (статических) переменных при конкретизации шаблона
Объявлены следующие классы
template <typename T>
class Z
{
static constexpr std::size_t N{0};
static constexpr std::array<int, N> v_static{};
const std::array<double, N> v{};
};
class X: Z<X>{};
С инициализацией N проблем не возникает
template<>
constexpr std::size_t Z<X>::N = 3;
Но как конкретизировать v и v_static для Z< X >? Следующий код не работает
template<>
std::array<int, Z<X>::N> Z<X>::v_static = { 4, 5, 6 };
template<>
const std::array<double, Z<X>::N> Z<X>::v = {3.14, 2.7, 0.1};
Ответы (1 шт):
как исправить данный код, чтобы он компилировался?
Определить полную специализацию Z для X:
template<>
class Z<X>
{
static constexpr std::size_t N { 3 };
static constexpr std::array<int, N> v_static { 4, 5, 6 };
const std::array<double, N> v { 3.14, 2.7, 0.1 };
};
Но как конкретизировать v и v_static для Z< X >? Следующий код не работает
После того, как Вы дали определение X, компилятор уже сгенерировал специализацию Z<X>, и в этой специализации Z<X>::N все еще равен нулю, равно как и Z<X>::v_static имеет тип std::array<int, 0>. Когда Вы пытаетесь дать определение, после того, как изменили значение N, Вы фактически меняете тип v_static на std::array<int, 3>. Разумеется, это невозможно.
Что касается out-of-class определения template<> constexpr std::size_t Z<X>::N = 3;, оно у меня вызывает подозрения :) Давать out-of-class определение static constexpr члену-данных все еще можно (а иногда и нужно, зависит от стандарта C++), но без инициализатора, т.е.:
template<typename T>
constexpr std::size_t Z<T>::N;