2012-06-30 17 views
5

Bu üye fonksiyon testi vardır:SFINAE üye fonksiyon varlığı testi sorunu

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

verilen isimdeki üye işlevi vardır zaman fonksiyonu hiçbir götüren bir aşırı vardır durumda, doğru olarak değerlendirilir argümanlar. Bu tür işlevler için ve STL kapsayıcılarında, her zaman yanlış olarak değerlendirdiği eleman erişim işlevleri (ön, arka vb.) Dışında düzgün çalışır.

Neden? Ben mingw g ++ 4.7 var.

+0

Takip eden dönüş tipi yardımına geçiyor mu? auto f (U * p) -> decltype (p-> üye(), true_type()); – Xeo

cevap

6

Bunun nedeni, bu işlevlerin başvuruları döndürmesidir ve geri dönen değere bir gösterici beyan ediyorsunuz demektir, bu bir referansın göstericisidir ve bu imkansızdır. Hataların Bu tür SFINAE başarısız olduğunda bir hata vermek için derleyici zorlarsanız çözmek için (nispeten) kolay olabilir ve bunu düşünüyorum:

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

PS:

hızlı düzeltme olacağını yapmamalı.

Kodunuzda, yalnızca false_type yorumunu yapın ve true_type tek seçenek olduğunda derleyiciden hataları görün. Anlamsız çizgilerin bir buch'i arasında aşağıdakiler vardır:

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

Teşekkürler, işe yaradı. Ben de referans kaldırmadan bunu yapmak için bir yol anladım düşünüyorum: "typename Check = decltype (declval () .front()" ikinci bir şablon argümanı olarak, ve f yerine bir char işaretçisini geçirin. –

+0

@ AndrásKovács - Bu şekilde daha da iyi. – rodrigo