Шаблонный трюк для определения глобального массива в заголовке
Я наткнулся на такой трюк:
// 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;
}