2012-03-15 66 views
5

Domyślne argumenty szablonu mogą służyć do symulacji aliasów dla wyrażeń złożonych w deklaracji szablonu. Na przykład:Czy można symulować domyślne argumenty szablonów w częściowych specjalizacjach?

template <typename X, 
      typename Y = do_something_with<X>::type, 
      typename Z = some_other_thing_using<X, Y>::type 
struct foo { ... X, Y, Z ... }; 

Jednak częściowe specjalizacje nie może mieć argumenty domyślne szablonu ([C++11: 14.5.5/8]), więc ta sztuczka nie działa. Możesz zadać sobie pytanie, dlaczego typedef w ciele nie zadziałał, a odpowiedź brzmi, że aliasy muszą znajdować się w zakresie przed ciałem klasy, aby umożliwić warunkowe włączenie; np:

template <typename T, typename Enable = void> 
struct bar; 

// Wishful thinking: 
template <typename X, 
      typename Y = do_something_with<X>::type, 
      typename Z = some_other_thing_using<X, Y>::type> 
struct bar <std::vector<X>, 
      typename enable_if< 
       some_condition<X, Y, Z> 
      >::type> 
    { ... }; 

Sposób Pracowałem wokół niego korzysta typ pomocniczy:

template <typename X> 
struct bar_enabled { 
    typedef typename do_something_with<X>::type Y; 
    typedef typename some_other_thing_using<X, Y>::type Z; 
    static const bool value = some_condition<X, Y, Z>::value; 
}; 

template <typename X> 
struct bar <std::vector<X>, 
      typename enable_if_c< 
       bar_enabled<X>::value 
      >::type> 
    { ... }; 

ale z różnych powodów (m.in. chcąc uniknąć osobny typ, który komplikuje, co mam robi), mam nadzieję, że istnieje lepsze rozwiązanie. Jakieś pomysły?

+1

domyślne nic nie symulować. Zapewniają wartości domyślne. –

+3

Dla rekordu: "Lista parametrów szablonu specjalizacji nie zawiera domyślnych wartości argumentów szablonu" '[C++ 11: 14.5.5/8]' –

+0

@LightnessRacesinOrbit, czy chcesz podkreślić, że problem ten nie występuje? t zmieniono w C++ 11, czy coś innego? – ajg

Odpowiedz

3

Może trzymać z podziałem na klasy bazowej: argumenty

template <typename X, typename Y, bool> 
struct BaseImpl    { /* ... */ }; 

template <typename X, typename Y> 
struct BaseImpl<X, Y, true> { /* ... */ }; 

template <typename X, typename Y = typename weird_stuff<X>::type> 
struct Foo : BaseImpl<X, Y, some_condition<X, Y>::value> 
{ 
    // common stuff 
}; 
Powiązane problemy