根据类模板的typename生成一个字符串?

时间:2013-05-15 10:20:52

标签: c++ class templates macros c-preprocessor

我希望能做什么...

我有一个模板化的类,它根据作为类型参数传递的对象类型设置(命名)共享内存池。我想知道是否可能通过preprocessor operators或其他方式帮助“字符串化”类型名称并附加标识符?

语法的一些内容: < classtype> _identifier
MyClass<int>会产生int_identifier ...的人 例如:

template<typename T>
class MyClass
{
private:
    #define TYPENAME_STRING(s) T_#s
    std::string m_typeName;

public:
    MyClass(std::string objName = "ObjectName")
    {
        // This:
        m_typeName = TYPENAME_STRING(objName.c_str());
        // ...Obviously doesn't work, since this is the equivalent of typing:
        m_typeName = "T_ObjectName";
        // ...When what we really want is something like:
        m_typeName = "int_ObjectName";
    }
    ~MyClass();        
};


完全根据作为类型参数传递的对象类型来命名,创建和管理伪独特内存池是很有用的。

这样的事情可能吗?

同样,是否可以解析此类型名称并将其添加到标识符 WITHOUT 为“stringized”(即创建一个名为 intObjectName)?

3 个答案:

答案 0 :(得分:6)

不,这是不可能的,至少不是那个级别。在编译之前评估宏,即在评估示例中的T等模板类型参数之前。你可以做的是这样的事情:

#include <string>
#include <memory>
template <class T> struct TInfo;
template <class T> class MyClass;

#define TINFO(type)                                \
template <> struct TInfo<type> {                   \
  static char const* getName() {                   \
    return #type;                                  \
  }                                                \
};                                                 \
typedef MyClass<type> type##_Class;                \
typedef std::unique_ptr<MyClass<type>> type##_UPtr; 


template <class T>
class MyClass {
private:
  std::string m_typeName;

public:
  MyClass(std::string objName = "ObjectName") 
    : m_typeName(std::string(TInfo<T>::getName()) + "_" + objName)
  {}

  std::string const& getName() {
    return m_typeName;
  }
};


//usage:
#include <iostream>

TINFO(int);
int main()
{
  int_UPtr pi(new int_Class());
  std::cout << pi->getName() << '\n';
}

请参阅http://ideone.com/3ivyqv

答案 1 :(得分:3)

您可以使用它来将您的类型字符串化:

template <typename T>
class MyClass {
public:
    static const char *name; // Not private
// ...
};

#define DECLARE_MY_CLASS(x) template<> const char *MyClass<x>::name = #x;

DECLARE_MY_CLASS(int);

但您需要DECLARE_MY_CLASS您要使用的所有类型。

答案 2 :(得分:0)

我可能误读了这个,但您可以使用typeid获取typename的字符串,如下所示:

template <typename T>
class MyClass 
{
private:
  const static std::string s_typeName;

public:

  const std::string getName() const 
  {
      return s_typeName;
  }
};

template<typename T>
const std::string MyClass<T>::s_typeName = std::string(typeid(T).name()) + "_identifier";