2014-09-02 7 views
5

Istnieje kilka sposobów implementacji szablonu has_type<T>, który pozwala ustalić, czy T ma klasę zagnieżdżoną lub typedef o nazwie type. tjhas_type template zwraca true dla typu struktury {};

namespace detail { 
    template<typename> struct tovoid { typedef void type; }; 
} 

template<typename T, typename = void> struct has_type 
    : std::false_type { }; 
// this one will only be selected if C::type is valid 
template<typename C> struct has_type<C, typename detail::tovoid<typename C::type>::type> 
    : std::true_type { }; 

Albo

template <typename C> char test_for_type(...) { return '0'; } 
template <typename C> double test_for_type(typename C::type const *) { return 0.0; } 

template <typename T> struct has_type 
{ 
    static const bool value = sizeof(test_for_type<T>(0)) == sizeof(double); 
}; 

jednak w obu przypadkach has_type<type>::value jest true dla tej klasy:

struct type 
{ 
}; 

Teraz powyżej type nie ma innego type zagnieżdżone w nim, ale ma konstruktora type::type().

Ale czy ten konstruktor "uruchamia" sprawdzenia dla typu zagnieżdżonego? Czy jest to błąd kompilatora? (Chciałbym myśleć, że typename type::type nie stosuje się do konstruktora i/lub, że nie można przyjąć wskaźnik do konstruktora, takich jak to, co będzie produkowane przez drugą metodą badania. typename type::type const *

?

Odpowiedz

5

Nazwa klasy jest „wstrzykiwany” do zakresu klasy, więc type::type naprawdę jest nazwą typu, i to jest tego samego typu co ::type.

+1

Ach, prawda. i myślę, że 'struct typ {struct type {};}; 'jest nieprawidłowy, podobnie jak' struct type {typedef int type;}; '. Który odpowiada na moje następne pytanie - jak sobie z tym poradzić (jeśli naprawdę chciałem). autor: ch ekking, jeśli T jest nazwą typu, co nie powinno być zbyt trudne. – tony

+0

i dzięki za szybką odpowiedź! – tony

+0

@tony Trudniejsze i mniej przenośne niż mogłoby się wydawać: http://stackoverflow.com/q/1055452/501250 – cdhowie