2012-01-17 178 views
2

我在C++中有一个模板函数,基本上将值写入XML文件,出于验证目的,我希望写出变量类型及其值。我目前使用typeid(T).name()这对于int的伟大工程,double等,但我想,这样它总是写出“串”或东西比更有意义的char阵列和std::string一个特殊情况:C++模板T,检测类型是字符串的形式

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; 
    } 

回答

10

您可以使用一个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; 
    } 
+0

简单而不失优雅+1 – 2012-01-17 10:26:42

+0

我不知道我跟着,我怎么添加这个我的代码?我用我的示例代码更新了我的问题。 – Chris 2012-01-17 10:27:47

+0

@Chris:我添加了代码的必要修改。 – 2012-01-17 10:31:05

4

你可以用里面的垫片功能的类型。这些函数实际上并不需要定义,因为它们不会被执行;你只需要声明来使用重载解析来为你选择正确的函数,所以你可以用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; 
} 
+0

你仍然需要'char [N]'的版本,因为如果OP有的模板是用'char [N]'实例化的,那么它不会是该functino中的文字,而模板版本的shim将被选中。 – 2012-01-17 11:01:58

+0

是的。但我更喜欢你的解决方案:D 我认为我可以通过使用重载来“增强”你的,从而避免定义许多模板类。 – bronekk 2012-01-17 11:24:03

相关问题