2

我希望能够做什么...

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

类似于语法的东西:<classtype>_identifier
Where MyClass<int>would generate 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();        
};


让它工作对于完全基于作为类型参数传递的对象类型来命名、创建和管理伪唯一内存池很有用。

这样的事情可能吗?

此外,是否可以解析此类型名并将其添加到标识符而不被“字符串化”(即,创建一个名为 intObjectName的 typedef )?

4

3 回答 3

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

于 2013-05-15T10:43:53.757 回答
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你想要使用的所有类型。

于 2013-05-15T10:52:11.677 回答
0

我可能误读了这一点,但您可以使用 typeid 获取类型名的字符串,如下所示:

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";
于 2014-10-24T12:38:59.067 回答