头文件c ++ 11中的C ++静态const字符串

时间:2014-05-13 16:48:45

标签: c++ string c++11 entity const

我想写一个提供有限RTTI信息的课程。

现在我想要的是这样的

template<typename T>
struct isGameComponent
{
   public:
   static_assert(false,"If a non-specialized version is created we have problems");
}

template<>
struct isGameComponent<Transform>
{
  public:
  static const char* COMPONENT_TYPE_NAME = "Transform";
  static const uint32_t COMPONENT_TYPE_ID = HashString("Transform"); //constexpr 
};

//Do this a lot more

虽然我不能初始化字符串,因为它不是文字类型,但我收到编译时错误。我只想保留这个lib头。这不可能吗?

2 个答案:

答案 0 :(得分:2)

要将模块保留为标题,只有几个选项:

  • inline返回值的函数。
  • 模板化常数技巧。
  • C ++ 11 constexpr关键字。

内联函数示例:

template<typename T>
struct IsGameComponent;

template<>
struct IsGameComponent<Transform>
{
    static
    auto componenTypeName()
        -> const char*
    { return "Transform"; }

    static
    auto componentTypeId()
        -> uint32_t
    {
        static uint32_t const theId = hashString("Transform");
        return the_id;
    }
};

模板化常量技巧的例子:

template<typename T>
struct IsGameComponent;

template< class Dummy_ >
struct C_IsGameComponent_Transform
{
    static char const* const componentTypeName;
    static uint32_t const componentTypeId;
};

template< class D >
char const* const C_IsGameComponent_Transform<D>::componentTypeName = "Transform";

template< class D >
uint32_t const C_IsGameComponent_Transform<D>::componentTypeId  = hashString( "Transform" );

template<>
struct IsGameComponent<Transform>
    : C_IsGameComponent_Transform<void>
{
    // Constants available here.
};

C ++ 11 constexpr示例(这要求hashStringconstexpr函数):

template<typename T>
struct IsGameComponent;

template< class Dummy_ >
struct C_IsGameComponent_Transform
{
    static char const* constexpr componentTypeName = "Transform";
    static uint32_t constexpr componentTypeId = hashString( "Transform" );
};

使用此解决方案,您无法获取任何这些常量的地址。


免责声明:以上代码均未附近任何C ++编译器。

答案 1 :(得分:1)

从类声明中定义那些静态成员:

const char *isGameComponent<Transform>::COMPONENT_TYPE_NAME = "Transform";

const uint32_t isGameComponent<Transform>::COMPONENT_TYPE_ID = HashString("...");

如果将这些定义放在头文件中,那么每个翻译单元中都会有多个静态,这可能会导致一些问题。如果你把它们放在一个cpp文件中,你就有一个,建议使用它。