2016-03-08 66 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,最好在另一個問題中提出這個問題。 –