2016-03-08 65 views
2

我有以下模板来检查类型是否为std::string。它在GCC上编译得很好,但在Clang上失败。哪一个是正确的行为?有没有办法让它在两个方面都有效?上锵编译时函数评估,不完整类型

#include<iostream> 
#include<string> 
#include<type_traits> 

using namespace std; 

template <typename T> //Checks if T is string type, by testing for the existence of member type "traits_type" 
class is_string 
{ 
public: 
    template<typename C> std::false_type test(...); 
    template<typename C> std::true_type test(decltype(sizeof(typename C::traits_type))); 

    enum { 
    value = decltype(((is_string<T>*)nullptr) -> test<T>(sizeof(0)))::value 
    }; 
}; 

int main() { 
cout<<is_string<string>::value<<endl; 
} 

错误:

trial.cpp:15:51: error: member access into incomplete type 'is_string<std::basic_string<char> >' 
    value = decltype(((is_string<T>*)nullptr) -> test<T>(sizeof(0)))::value 
              ^
trial.cpp:20:7: note: in instantiation of template class 'is_string<std::basic_string<char> >' requested here 
cout<<is_string<string>::value<<endl; 
    ^
trial.cpp:8:7: note: definition of 'is_string<std::basic_string<char> >' is not complete until the closing '}' 
class is_string 
+3

有什么奇怪的方法来检查,如果一个类型是的std :: string ...... – SergeyA

+0

我看到现在。元编程还很新颖。 – SPMP

回答

5

铛是正确的,因为,因为它说,直到它完成所定义的类型是不完整的。我想如果你打开-pedantic那么你也会在gcc中出错。

更简单的方法做你想要的是只使用std::is_same

#include <string> 
#include <type_traits> 

static_assert(std::is_same<std::string, std::string>::value, ""); 
static_assert(not std::is_same<std::string, int>::value, ""); 
+0

我确实有其他的模板可以做类似的事情,但不像使用'is_same''那么简单。在这种情况下我应该做什么? – SPMP

+0

@ user2308211:这取决于你在做什么,但通常你可以(1)只使用SFINAE来启用/禁用代码,不要使用特性,或者(2)查看模板std :: enable_if',也是'void_t':http://stackoverflow.com/questions/27687389/how-does-void-t-work –

+0

如果对别人有用,我最后去了 ''模板'' ''使用is_string = std :: is_same ;'' – SPMP

0

是否g++的问题是对还是clang是对已经是answered by @ChrisBeck

您可以简化您的实现:

template <typename T> 
struct is_string 
{ 
    static bool const value = std::is_same<std::string, T>::value; 
}; 
+0

我确实需要其他用途的类似模板。一般来说,检查一个班级是否有特定的成员。我如何正确地做到这一点? – SPMP

+0

@ user2308211,最好在另一个问题中提出这个问题。 –