2012-08-13 153 views
10

我寫了下面的代碼,試圖檢測一個類型是否有靜態成員變量。不幸的是,它總是返回變量不存在。sfinae檢查靜態成員使用decltype

有人能告訴我我要去哪裏嗎?我正在使用g ++ 4.7.1。

#include <iostream> 
#include <utility> 
#include <type_traits> 

using namespace std; 

template <class T>             
class has_is_baz               
{                 
    template<class U, 
      typename std::enable_if<std::is_same<bool, decltype(U::is_baz)>::value>::type...>      
     static std::true_type check(int);       
    template <class>             
     static std::false_type check(...);       
public:                
    static constexpr bool value = decltype(check<T>(0))::value;  
}; 

struct foo { }; 

struct bar 
{ 
    static constexpr bool is_baz = true; 
}; 

int main() 
{ 
    cout << has_is_baz<foo>::value << '\n'; 
    cout << has_is_baz<bar>::value << '\n'; 
} 

回答

8

的主要問題是:

std::is_same<bool, decltype(bar::is_baz)>::value == false 

然後你SFINAE總​​是失敗。我已經重新編寫的has_is_baz特點和它現在的作品:

#include <iostream> 
#include <utility> 
#include <type_traits> 

using namespace std; 

template <class T>             
class has_is_baz               
{  
    template<class U, class = typename std::enable_if<!std::is_member_pointer<decltype(&U::is_baz)>::value>::type> 
     static std::true_type check(int); 
    template <class> 
     static std::false_type check(...); 
public: 
    static constexpr bool value = decltype(check<T>(0))::value; 
}; 

struct foo { }; 

struct bar 
{ 
    static constexpr bool is_baz = true; 
}; 

struct not_static { 
    bool is_baz; 
}; 

int main() 
{ 
    cout << has_is_baz<foo>::value << '\n'; 
    cout << has_is_baz<bar>::value << '\n'; 
    cout << has_is_baz<not_static>::value << '\n'; 
} 

演示here

編輯:我已經修復了類型特徵。正如@litb指出的那樣,它正在檢測靜態成員以及非靜態成員。

+0

這並不要求'U :: is_baz'是靜態的。一個'struct A {bool is_baz; };'也會工作。 – 2012-08-14 21:50:34

+0

@ JohannesSchaub-litb你是對的。它現在看起來很有效。 – mfontanini 2012-08-14 22:19:32

5

在你的代碼的問題是,一個constexpr對象是隱含const,這意味着你對同一類型的測試應該是:

std::is_same<const bool, decltype(U::is_baz)>::value 

這在標準中指定了§7.1.5[DCL。 constexpr]/9

在對象聲明中使用的constexpr說明符將該對象聲明爲const。 [...]