2012-06-30 25 views
5

我有這樣的成員函數測試:SFINAE成員函數存在測試問題

template <typename T> 
struct has_member { 
    template <typename U> static true_type f(decltype(declval<U>().member()) *); 
    template <typename> static false_type f(...); 
    static const bool value = decltype(f<T>(0))::value; 
}; 

它評估爲真時,存在一個給定的名稱的成員函數,該函數有一個重載不帶任何情況參數。對於這樣的函數,在STL容器的情況下,除了元素訪問函數(正面,背面等)之外,它正常工作,它總是評估爲false。

這是爲什麼?我有mingw g ++ 4.7。

+0

是否更改爲結尾返回類型幫助? 'auto f(U * p) - > decltype(p-> member(),true_type());' – Xeo

回答

6

這是因爲這些函數返回引用,並且你正在聲明一個指向返回值的指針,這是一個指向引用的指針,這是不可能的。

速戰速決將是:

template <typename U> static true_type 
     f(typename remove_reference< decltype(declval<U>().member()) >::type *); 

PS:這樣的錯誤可以(相對)容易,如果你強迫編譯時SFINAE未能給予一個錯誤來解決,你認爲它不應該。

我的意思是,在您的代碼中,只需將false_type註釋掉,並在true_type是唯一選項時查看編譯器中的錯誤。在多行無意義行之間存在以下內容:

test.cpp:9:50: error: forming pointer to reference type 
    ‘__gnu_cxx::__alloc_traits<std::allocator<int> >::value_type& {aka int&}’ 
+0

謝謝,這很有效。我想我也想出了一種不刪除引用的方法:我將「typename Check = decltype(declval ().front()」作爲第二個模板參數,並且使f傳遞一個字符指針 –

+0

@ AndrásKovács - 更好的方式。 – rodrigo