C++模板T,检测类型为字符串形式

C++ template T, detecting Type is form of string

本文关键字:字符串 类型 检测 模板 C++      更新时间:2023-10-16

我在C++中有一个模板函数,它基本上将值写入XML文件,出于验证目的,我希望写出变量类型及其值。我目前使用的是typeid(T).name(),它适用于intdouble等,但我想要char阵列和std::string的特殊情况,以便它总是写出"字符串"或比更有意义的东西

class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >

char const  [2]

关于我如何以优雅的方式做到这一点,有什么想法吗?

我的代码(精简版)看起来是这样的(不是函数只是模板)

  template <typename T> bool SetValue(const std::string &sectionName, const std::string &valueName, const T &value)
  {
      myXMl->AddAttribute(TYPE_DEF,typeid(T).name());
      return true;
  }

您可以为此使用traits类:

template<class T>
class type_name {
public:
    static std::string get() { return typeid(T).name(); }
};

此模板实现默认情况。现在,您可以将其专门化为应该具有特殊名称的类型:

template<>
class type_name<std::string> {
public:
    static std::string get() { return "string"; }
};
template<>
class type_name<const char *> {
public:
    static std::string get() { return "string"; }
};
template<int N>
class type_name<const char[N]> {
public:
    static std::string get() { return "string"; }
};

然后你的代码会是这样的:

template <typename T> bool SetValue(const std::string &sectionName, 
                                    const std::string &valueName, const T &value)
  {
      myXMl->AddAttribute(TYPE_DEF, type_name<T>::get());
      return true;
  }

您可以将类型封装在填充程序函数中。这些函数实际上不需要定义,因为它们永远不会被执行;您只需要声明就可以使用重载解析来为您选择合适的函数,因此您可以使用typeid()表达式获取其结果的类型。

请记住,模板函数仅用于完美匹配,而非模板函数的重载允许隐式转换。

示例:

#include <string>
#include <iostream>
#include <typeinfo>
struct string{};
template <typename T> T shim(T);
// Not needed, literals will be matched by (const char*) below
// template <size_t S> string shim(const char (&)[S]);
string shim(const char*);
string shim(const std::string&);
int main()
{
  std::cout << typeid(shim(1.0)).name() << "n"
            << typeid(shim(true)).name() << "n"
            << typeid(shim(0)).name() << "n"
            << typeid(shim((void *)NULL)).name() << "n"
            << typeid(shim("hello there")).name() << "n"
            << typeid(shim((const char*)"hello there")).name() << "n"
            << typeid(shim(std::string("hello there"))).name() << std::endl;
}