Шаблонный трюк для определения глобального массива в заголовке

Я наткнулся на такой трюк:

// This template utilizes the One Definition Rule to create global arrays in a header.
template<typename unused=void>
struct globals_struct
{
   static const uint8 s_str_serialize_flags[256];
   // ...
};
typedef globals_struct<> globals;

template<typename unused>
const uint8 globals_struct<unused>::s_str_serialize_flags[256] =
{
// ... data here ...
};
   // ... and then the array is accessible as:
   uint8 value = globals::s_str_serialize_flags[index])

Этот код взят из Purple JSON Рича Гелдрейха, о котором я узнал из блога Чеда Остина.

Прежде чем увидеть этот код, я подумал, что единственный способ иметь массив в библиотеке только для заголовка - это потребовать от пользователя #define Волшебный макрос ровно в одном файле (перед включением заголовка).

Так что мне нравится трюк с шаблонами, но мне интересно:

  • это идиома C++ (у нее есть имя)?
  • это стандарт и безопасно для использования?
  • такое обертывание шаблона - самый простой способ иметь массив в заголовке?

Редактировать: я только что натолкнулся на тот же трюк в SO-ответе, где он показан как альтернатива встроенным переменным C++17.

1 ответ

Решение

Для меня самое простое - это обернуть его в функцию (и std::array)

using arr256 = std::array<std::uint8_t, 256>;

inline constexpr arr256 s_str_serialize_flags() {
    constexpr arr256 values = {/**/};
    return values;
}

или без constexpr ограничение:

using arr256 = std::uint8_t[256];

inline const arr256& s_str_serialize_flags() {
    static const arr256 values = {/**/};
    return values;
}
Другие вопросы по тегам