【问题标题】:Large static arrays in header only implementation仅标题实现中的大型静态数组
【发布时间】:2013-06-26 19:29:51
【问题描述】:

由于需要能够在仅标头实现中引用 unicode 字符组,我想先声明所有数组。模板允许我在标头中初始化静态成员,但代码看起来很乱。

这只是二十多个组中的两个:

struct CharacterClass 
{
    struct Value
    {
        int l;
        int h;
    };
};

template < int N >
struct Nd : public CharacterClass
{
    static const Value v[];
};

template< int N >
const typename Nd< N >::Value Nd< N >::v[] = { 
    { 0x00030 ,  0x00039 }, { 0x00660 ,  0x00669 }, { 0x006f0 ,  0x006f9 }, { 0x007c0 ,  0x007c9 }, { 0x00966 ,  0x0096f },
    { 0x009e6 ,  0x009ef }, { 0x00a66 ,  0x00a6f }, { 0x00ae6 ,  0x00aef }, { 0x00b66 ,  0x00b6f }, { 0x00be6 ,  0x00bef },
    { 0x00c66 ,  0x00c6f }, { 0x00ce6 ,  0x00cef }, { 0x00d66 ,  0x00d6f }, { 0x00e50 ,  0x00e59 }, { 0x00ed0 ,  0x00ed9 },
    { 0x00f20 ,  0x00f29 }, { 0x01040 ,  0x01049 }, { 0x017e0 ,  0x017e9 }, { 0x01810 ,  0x01819 },     { 0x01946 ,  0x0194f },
    { 0x019d0 ,  0x019d9 }, { 0x01b50 ,  0x01b59 }, { 0x0ff10 ,  0x0ff19 }
};

template < int N >
struct Nl : public CharacterClass
{
    static const Value v[];
};
template< int N >
const typename Nl< N >::Value Nl< N >::v[] = { 
    { 0x016ee ,  0x016f0 },     { 0x02160 ,  0x02182 },  { 0x03007, 0x03007 },  { 0x03021 ,  0x03029},  { 0x03038 ,  0x0303a }
};

Q1:是否可以在基类中声明一次数组,而不必为每个派生类型重复它?

Q2:如何隐藏 dummy 'int N',以便以后无需添加模板参数即可引用结构? IE。 int x = Nd.v[10].l;

Q3:有更好的方法吗?

【问题讨论】:

    标签: c++ arrays templates static constants


    【解决方案1】:

    我将尝试为您提供您所要求的 Q1 的替代方案。 我不喜欢看到对程序逻辑没有意义的硬编码值。

    这是我有时会使用的一个好技巧:

    创建一个新文件并将值粘贴到其中。

    data.dat

    { 0x00030 ,  0x00039 }, { 0x00660 ,  0x00669 }, { 0x006f0 ,  0x006f9 }, { 0x007c0 ,  0x007c9 }, { 0x00966 ,  0x0096f },
    { 0x009e6 ,  0x009ef }, { 0x00a66 ,  0x00a6f }, { 0x00ae6 ,  0x00aef }, { 0x00b66 ,  0x00b6f }, { 0x00be6 ,  0x00bef },
    { 0x00c66 ,  0x00c6f }, { 0x00ce6 ,  0x00cef }, { 0x00d66 ,  0x00d6f }, { 0x00e50 ,  0x00e59 }, { 0x00ed0 ,  0x00ed9 },
    { 0x00f20 ,  0x00f29 }, { 0x01040 ,  0x01049 }, { 0x017e0 ,  0x017e9 }, { 0x01810 ,  0x01819 },     { 0x01946 ,  0x0194f },
    { 0x019d0 ,  0x019d9 }, { 0x01b50 ,  0x01b59 }, { 0x0ff10 ,  0x0ff19 }
    

    现在,当您想重复时,请执行以下操作:

    const typename Nd< N >::Value Nd< N >::v[] = { 
    #include "data.dat"
    };
    

    这样,预处理器将为您粘贴所有这些值,因此您无需一直重复它们。

    【讨论】:

    • +1 一个巧妙的技巧。将来肯定会派上用场。但是这段代码需要是一个单独的头文件。
    • @Waldermort:是单个头文件; data.dat 不是头文件。
    • 谁说必须是头文件?
    【解决方案2】:

    回答我自己的问题。我将整个组合数组放在一个基类中,然后从该基类派生,派生类型将自身初始化为数组中的索引。

    struct CharacterClass 
    {
        struct Value
        {
            int l;
            int h;
        };
    };
    
    template < int X >
    struct Base : public CharacterClass
    {
        static const Value v[];
    };
    template< int X >
    const typename Base< X >::Value Base< X >::v[] = { 
        // Nd values length 23 index 0
        { 0x00030 ,  0x00039 }, { 0x00660 ,  0x00669 }, { 0x006f0 ,  0x006f9 }, { 0x007c0 ,  0x007c9 }, { 0x00966 ,  0x0096f },
        { 0x009e6 ,  0x009ef }, { 0x00a66 ,  0x00a6f }, { 0x00ae6 ,  0x00aef }, { 0x00b66 ,  0x00b6f }, { 0x00be6 ,  0x00bef },
        { 0x00c66 ,  0x00c6f }, { 0x00ce6 ,  0x00cef }, { 0x00d66 ,  0x00d6f }, { 0x00e50 ,  0x00e59 }, { 0x00ed0 ,  0x00ed9 },
        { 0x00f20 ,  0x00f29 }, { 0x01040 ,  0x01049 }, { 0x017e0 ,  0x017e9 }, { 0x01810 ,  0x01819 },     { 0x01946 ,  0x0194f },
        { 0x019d0 ,  0x019d9 }, { 0x01b50 ,  0x01b59 }, { 0x0ff10 ,  0x0ff19 },
    
        // Nl values length 5 index 23
        { 0x016ee ,  0x016f0 }, { 0x02160 ,  0x02182 },  { 0x03007, 0x03007 },  { 0x03021 ,  0x03029},  { 0x03038 ,  0x0303a }
    };
    
    template < int _index, int _length >
    struct BaseIndex : public Base< 0 >
    {
        static const Value * v;
        static const int length;
    };
    template < int _index, int _length >
    const typename BaseIndex< _index, _length >::Value * BaseIndex< _index, _length >::v = &Base::v[ _index ];
    template < int _index, int _length >
    const int BaseIndex< _index, _length >::length = _length;
    
    struct Nd : public BaseIndex< 0, 23 >
    {
    };
    struct Nl : public BaseIndex< 23, 5 >
    {
    };
    

    我认为只是命名空间中的 typedef 可以替换那些结构的 Nd 和 Nl。

    如果有更好的方法,我仍然愿意接受建议。

    【讨论】:

      猜你喜欢
      • 2011-09-11
      • 1970-01-01
      • 2017-10-29
      • 1970-01-01
      • 1970-01-01
      • 2018-06-12
      • 2014-07-21
      • 2013-10-23
      • 2012-01-15
      相关资源
      最近更新 更多