Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 基于类模板生成字符串';你的姓是什么? 我想做的是。。。_C++_Class_Templates_Macros_C Preprocessor - Fatal编程技术网

C++ 基于类模板生成字符串';你的姓是什么? 我想做的是。。。

C++ 基于类模板生成字符串';你的姓是什么? 我想做的是。。。,c++,class,templates,macros,c-preprocessor,C++,Class,Templates,Macros,C Preprocessor,我有一个模板类,它根据作为类型参数传递的对象类型设置一个(命名的)共享内存池。我想知道是否有一种方法可以“字符串化”类型名,并附加一个标识符? 语法大致如下:\u标识符 其中,MyClass将生成int\u标识符。 例如: template<typename T> class MyClass { private: #define TYPENAME_STRING(s) T_#s std::string m_typeName; public: MyClass(s

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

语法大致如下:\u标识符
其中,
MyClass
将生成
int\u标识符

例如:

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();        
};
模板
类MyClass
{
私人:
#定义TYPENAME_字符串T#s
std::字符串m_typeName;
公众:
MyClass(std::string objName=“ObjectName”)
{
//这:
m_typeName=typeName_字符串(objName.c_str());
//…显然不起作用,因为这相当于键入:
m_typeName=“T_ObjectName”;
//…当我们真正想要的是:
m_typeName=“int_ObjectName”;
}
~MyClass();
};

使其正常工作对于完全基于作为类型参数传递的对象类型命名、创建和管理psuedo唯一内存池非常有用。

这样的事情可能吗?
此外,是否可以解析此typename并将其前置到标识符,而不进行“字符串化”(即,创建名为
的typedef到Object Name
)?

否,这是不可能的,至少在该级别不可能。宏是在编译之前计算的,也就是说,在计算模板类型参数(如示例中的
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';
}
#包括
#包括
模板结构TInfo;
模板类MyClass;
#定义TINFO(类型)\
模板结构TInfo{\
静态字符常量*getName(){\
返回#类型\
}                                                \
};                                                 \
类型定义MyClass类型###U类\
typedef std::unique_ptr type###u UPtr;
模板
类MyClass{
私人:
std::字符串m_typeName;
公众:
MyClass(std::string objName=“ObjectName”)
:m_typeName(std::string(TInfo::getName())+“_”+objName)
{}
std::string const&getName(){
返回m_typeName;
}
};
//用法:
#包括
TINFO(int);
int main()
{
int_UPtr pi(新的int_类());

std::cout getName()您可以使用此命令将类型字符串化:

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);
模板
类MyClass{
公众:
静态常量char*name;//非私有
// ...
};
#定义DECLARE_MY_CLASS(x)template const char*MyClass::name=#x;
声明我的类(int);

但是您需要
声明\u MY\u CLASS
您想要使用的所有类型。

我可能误读了这一点,但是您可以使用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";
模板
类MyClass
{
私人:
常量静态标准::字符串s_类型名;
公众:
常量std::string getName()常量
{
返回s_typeName;
}
};
模板
常量std::string MyClass::s_typeName=std::string(typeid(T).name())+“_标识符”;

+1关于我的示例不起作用的原因,再加上一个有效的示例。但是,是否还有一种方法可以生成使用相同命名约定的typedef?不过,请尽量使宏内容尽可能简短明了。调试是不可能的,并且宏代码产生的编译器错误很难解决。仅供参考,您不需要这样做错误,
.name()
的返回值依赖于实现,本身通常不“有用”。例如,
无符号int
在我的编译器上作为
“j”
返回。