我有一个模板化的类,它根据作为类型参数传递的对象类型设置(命名)共享内存池。我想知道是否可能通过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
)?
答案 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';
}
答案 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";