6

üye işlev işaretçi türleri dönüş türüne göre 'özel' sınıf şablonu, uzmanlaşmış girişiminde aşağıdaki kod, VC9 bir derleme hata ile sonuçlanır:Sınıf şablonu kısmi uzmanlık elemanı işlev dönüş tipine parametrize

template<class F> struct special {}; 
template<class C> struct special<void(C::*)()> {}; 
template<class R, class C> struct special<R(C::*)()> {}; 

struct s {}; 

int main() 
{ 
    special<void(s::*)()> instance; 
    return 0; 
} 

hata C2752: 'özel': http://ideone.com/ekWGg
: birden fazla kısmi uzmanlık ile gösterildiği gibi aynı kod GCC-4.3.4 tarafından kabul edilir

şablon bağımsız değişken bir liste ile karşılaştırılırBu VC9'da bir hata mı ve eğer öyleyse, bu hata VC10'un içinde kalmıştır?

Ben ancak (., En azından daha genel çözümler hoşgeldin bu özel kullanım durumu için) bir korkunç şekilde müdahaleci bir çözüm ile geldi:

#include <boost/function_types/result_type.hpp> 
#include <boost/type_traits/is_same.hpp> 

template<typename F, typename R> 
struct is_result_same : 
    boost::is_same< 
    typename boost::function_types::result_type<F>::type, 
    R 
    > 
{}; 

template<class F, bool = is_result_same<F, void>::value> 
struct special {}; 

template<class R, class C> struct special<R(C::*)(), true> {}; 
template<class R, class C> struct special<R(C::*)(), false> {}; 
+0

bu hayal sınıfını örnekler şablon uzmanlık daha özelleşmiş olan fonksiyon şablon 4. Ve sınıf şablonu uzmanlık daha özelleşmiş olan Çünkü, R'nin “void” olma durumu çözülürken, her iki özelliğin de imzaları aslında aynıdır… 'typename' anahtar sözcüğünün akıllıca kullanımı bazı faydalar sağlayabilir ama şu an zeki bir şey düşünemiyorum. – AJG85

cevap

3

Bu bir hata değildir.

template <class C> void f(special<void(C::*)()>);  // func-template 3 
template <class R, class C> void f(special<R(C::*)()>); // func-template 4 

göre 14.5.5.2 için, kısmi:

template <class C> struct special<void(C::*)()>;  // specialization 1 
template <class R, class C> struct special<R(C::*)()>; // specialization 2 

14.5.4.2 göre, bu iki sınıf şablon uzmanlık kısmi sıralama kısmi hayali fonksiyon şablonları sipariş aynıdır Bu iki fonksiyon şablonunun sıralanması, bir fonksiyonun argüman listesinde her bir tip şablon parametresi için icat edilen tiplerin ikame edilmesi ve diğer fonksiyon şablonunda bu argüman listesinin kullanılmasıyla şablon argüman indiriminin denenmesi ile belirlenir.

// Rewrite the function templates with different names - 
// template argument deduction does not involve overload resolution. 
template <class C> void f3(special<void(C::*)()>); 
template <class R, class C> void f4(special<R(C::*)()>); 

struct ty5 {}; struct ty6 {}; struct ty7 {}; 
typedef special<void(ty5::*)()> arg3; 
typedef special<ty6 (ty7::*)()> arg4; 

    // compiler internally tests whether these are well-formed and 
    // the resulting parameter conversion sequences are "exact": 
    f3(arg4()); 
    f4(arg3()); 

Şablon bağımsız değişkenin ayrıntıları 14.8.2'dir. Geçerli kesintiler arasında template_name<dependent_type> ve dependent_type1 (dependent_type2::*)(arg_list) bulunmaktadır. Yani kesinti, f4<void,ty5>(arg3()); çıkarılarak başarılı olur. void ve ty6 un birleştirilmemesi nedeniyle f3(arg4()) kesintisi kesinlikle başarılı olamaz.

nedenle fonksiyon şablonu 3 1 2. Yani special<void(s::*)()> rağmen maçları her iki uzmanlık, bu açık bir şekilde uzmanlaşma 1.

İlgili konular