【问题标题】:Template trick to define a global array in the header在标头中定义全局数组的模板技巧
【发布时间】:2017-09-07 14:56:51
【问题描述】:

我遇到了这样一个技巧:

// 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])

这段代码来自 Rich Geldreich 的 Purple JSON,我从 Chad Austin 的 blog 了解到。

在看到这段代码之前,我认为在仅标头库中拥有数组的唯一方法是要求用户在一个文件中(在包含标头之前)#define 一个魔术宏。

所以我喜欢模板包装技巧,但我想知道:

  • 它是 C++ 习语吗(有名字吗)?
  • 它是否符合标准且使用安全?
  • 这样的模板包装是在标题中包含数组的最简单方法吗?

编辑: 我刚刚在 SO answer 中遇到了同样的技巧,它被显示为 C++17 内联变量的替代方案。

【问题讨论】:

    标签: c++ global-variables header-files one-definition-rule


    【解决方案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;
    }
    

    【讨论】:

    • error: ‘values’ declared ‘static’ in ‘constexpr’ function
    • @marcin: 遗憾的是不允许那样做:-/ 由替代解决(保留constexpr)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-05
    • 2010-09-20
    • 2017-07-13
    相关资源
    最近更新 更多