C++ 带有静态字符*数组成员的模板专门化,以多个单位实例化

C++ 带有静态字符*数组成员的模板专门化,以多个单位实例化,c++,arrays,templates,static,C++,Arrays,Templates,Static,我有一个模板结构来存储静态字符*数组,如下所示: template<typename T> struct EnumStrings { static const char* const data[]; }; 因为我需要能够遍历这个数组,所以我被卡住了。。。有什么建议吗?当然,我不想在任何地方指定数组的大小,但这可能是唯一的可能性。在C++11中,以下工作: // In header: class SomeType; template<typename T> st

我有一个模板结构来存储
静态字符*
数组,如下所示:

template<typename T>
struct EnumStrings {
    static const char* const data[];
};

因为我需要能够遍历这个数组,所以我被卡住了。。。有什么建议吗?当然,我不想在任何地方指定数组的大小,但这可能是唯一的可能性。

在C++11中,以下工作:

// In header:

class SomeType;
template<typename T> struct EnumStrings;

template<>
struct EnumStrings<SomeType> {
    static constexpr
    const char* const data[] =
        {"item1", "item2", "item3", "item4"};
};

// in cpp, if address of data is taken.

constexpr
const char* const EnumStrings<SomeType>::data[];
//在标题中:
类SomeType;
模板结构枚举字符串;
模板
结构枚举字符串{
静态constexpr
常量字符*常量数据[]=
{“第1项”、“第2项”、“第3项”、“第4项”};
};
//在cpp中,如果采用了数据地址。
常量表达式
常量字符*常量枚举字符串::数据[];

您应该划分
数据的声明和定义。将其放入头文件:

template<typename T>
struct EnumStrings {
    static const char* const data[];
};

// declaration of `data` array specialization
template<> const char* const EnumStrings<SomeType>::data[4];

您可以将数据数组专门化的结构声明和定义放在匿名命名空间中。然后,结构将具有内部链接,这将防止出现多个定义错误

namespace {
template<typename T>
struct EnumStrings {
    static const char* const data[];
};
template<> const char* const EnumStrings<int>::data[] =
    {"item1", "item2", "item3", "item4"};
}
名称空间{
模板
结构枚举字符串{
静态常量字符*常量数据[];
};
模板常量字符*常量枚举字符串::数据[]=
{“第1项”、“第2项”、“第3项”、“第4项”};
}

< /代码>也许考虑使用<代码> STD::数组< /COD>替代静态成员函数?我已经实现了完全相同的行为。然而,我的实现使用了这样一个定义良好的接口:
std::string-ToString(const T&enumValue)。在两个
std::map
s下,使用类似于“双向图”的符号。通过将公共代码和专门化为两个独立类的代码分开(
Ènum
enuminpl
),不必复制粘贴公共代码(
std::map
,look up等;另一个非常重要的原因是延迟初始化,因为这些类的使用系统对于init来说非常复杂),但是必须专门化
enuminpl::Initialize()
当然我的方法有点慢(因为
std::map
不是静态的)。但是,我的用例与运行时无关,因此这不是一个大问题,在这种情况下,我更喜欢干净的代码而不是速度。不幸的是,这不起作用,因为我需要知道其他单元中数据的大小。这导致了我提到的第二个错误:
错误:“sizeof”对不完整类型“co”的应用无效nst char*const[]”
@OlivierB只需在
*.h
文件中添加数组的大小。我已经更正了我的答案。嗯,通过这个,我仍然得到了
对“EnumString::data”的多个定义
错误…我真的不明白为什么?@OlivierB你使用什么编译器?我使用的是gcc版本4.7.2(Debian 4.7.2-5)如果在多个单元中实例化,我看不出这会有什么变化?我仍然会遇到我提到的第一个错误:
多定义'EnumStrings::data'
@OlivierB想法是模板没有外部链接,因此这应该可以防止多定义错误。(
EnumStrings
EnumStrings
在不同的编译单元中编译时是不同的类)。我使用a.h中的struct测试了此设置,a.cpp和b.cpp包括它,并且匿名名称空间防止了预期的多个定义错误。如果没有匿名名称空间编译器,则会发出您提到的错误。它是有效的!我选择此答案是因为@Constructors的答案在Visual Studio 2012上不起作用。
// In header:

class SomeType;
template<typename T> struct EnumStrings;

template<>
struct EnumStrings<SomeType> {
    static constexpr
    const char* const data[] =
        {"item1", "item2", "item3", "item4"};
};

// in cpp, if address of data is taken.

constexpr
const char* const EnumStrings<SomeType>::data[];
template<typename T>
struct EnumStrings {
    static const char* const data[];
};

// declaration of `data` array specialization
template<> const char* const EnumStrings<SomeType>::data[4];
// definition of `data` array specialization
template<> const char* const EnumStrings<SomeType>::data[] =
    {"item1", "item2", "item3", "item4"};
namespace {
template<typename T>
struct EnumStrings {
    static const char* const data[];
};
template<> const char* const EnumStrings<int>::data[] =
    {"item1", "item2", "item3", "item4"};
}