Лучший способ - использовать базовый класс со специализацией и поместить sep
в базовый класс:
template <bool IsIntegral>
struct foo_base;
template<>
struct foo_base<true>
{
static constexpr char sep[3] = ". ";
};
template<>
struct foo_base<false>
{
static constexpr char sep[4] = ", ";
};
template<typename T>
struct foo : foo_base<std::is_integral_v<T>>
{
// many other things ...
};
Но если вы не хотите, чтобы другие получали доступ к базе, вы можете использовать приватныйНаследование:
template<typename T>
struct foo : private foo_base<std::is_integral_v<T>>
{
using foo_base<std::is_integral_v<T>>::sep;
// many other things ...
};
Редактировать
Преимущество этого решения по сравнению с использованием std::array<char, 3>
заключается в том, что это решение прекрасно работает с функциями, которые принимают ссылку на массивы Си char.Ни хранилище const char*
, ни std::array<char, 3>
не имеют такой возможности.
Например, если у вас есть такие функции, как:
template <std::size_t I>
constexpr int count_nuls(const char (&x)[I])
{
// Can't use std::count, since it is not constexpr
unsigned count = 0;
for (auto ch: x)
if (ch == '\0')
++count;
return count;
}
Эту функцию нельзя использовать с std::array
илис const char *
.Если таких функций много, возможно, вы не захотите обновить их все до std::array
.Например, эта функция отлично работает в:
static constexpr unsigned nuls = count_nuls(foo<double>::sep);
, но не будет работать (без дальнейшей модификации) с std::array<char, 3>
.