C++;模板T,检测类型为字符串形式 我在C++中有一个模板函数,它基本上将值写入XML文件,为了验证目的,我希望写出变量类型及其值。我目前正在使用typeid(T).name(),这对int、double等非常有效,但我希望对char数组和std::string有一个特殊情况,以便它总是写出“string”或比以下内容更有意义的内容: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >

C++;模板T,检测类型为字符串形式 我在C++中有一个模板函数,它基本上将值写入XML文件,为了验证目的,我希望写出变量类型及其值。我目前正在使用typeid(T).name(),这对int、double等非常有效,但我希望对char数组和std::string有一个特殊情况,以便它总是写出“string”或比以下内容更有意义的内容: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,c++,templates,types,std,C++,Templates,Types,Std,有没有办法让我以优雅的方式做到这一点 我的代码(删减)如下所示(并非函数仅为模板) template bool SetValue(常量std::string和sectionName,常量std::string和valueName,常量T和value) { myXMl->AddAttribute(TYPE_DEF,typeid(T).name()); 返回true; } 您可以为此使用traits类: template<class T> class type_name { public

有没有办法让我以优雅的方式做到这一点

我的代码(删减)如下所示(并非函数仅为模板)

template bool SetValue(常量std::string和sectionName,常量std::string和valueName,常量T和value)
{
myXMl->AddAttribute(TYPE_DEF,typeid(T).name());
返回true;
}

您可以为此使用traits类:

template<class T>
class type_name {
public:
    static std::string get() { return typeid(T).name(); }
};
模板
类类型名称{
公众:
静态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"; }
};
模板
类类型名称{
公众:
静态std::string get(){return“string”;}
};
模板
类类型名称{
公众:
静态std::string get(){return“string”;}
};
模板
类类型名称{
公众:
静态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;
  }
模板bool SetValue(const std::string和sectionName,
常量标准::字符串和值名称,常量T和值)
{
myXMl->AddAttribute(TYPE_DEF,TYPE_name::get());
返回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;
}
#包括
#包括
#包括
结构字符串{};
模板T垫片(T);
//不需要,文本将由下面的(const char*)匹配
//模板字符串填充(常量字符(&)[S]);
字符串垫片(常量字符*);
字符串垫片(常量标准::字符串&);
int main()
{

std::我不能确定我是否遵循,我如何将其添加到我的代码中?我用示例代码更新了我的问题。您仍然需要
char[N]
的版本,因为如果OP的模板是用
char[N]实例化的
,则该functino中不会包含文字,将选择
shim
的模板版本。是的,的确如此。我更喜欢您的解决方案,不过:D我认为我的解决方案可以通过使用重载来“增强”您的解决方案,从而避免定义太多模板类。
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;
  }
#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;
}