2012-03-15 18 views
5

Varsayılan şablon argümanları, şablon bildirimlerindeki karmaşık tip ifadeler için takma adları simüle etmek için kullanılabilir. Örneğin:Kısmi uzmanlıklarda varsayılan şablon argümanlarını simüle etmek mümkün mü?

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

Ancak kısmi uzmanlık varsayılan şablon argümanları olmayabilir ([C++11: 14.5.5/8]), bu nedenle bu hüner çalışmaz. Vücudunuzdaki bir yazımın neden işe yaramayacağını sormalısınız ve cevap, şartlı etkinleştirme yapabilmek için, takma adların sınıf gövdesinden önce kapsam içinde olması gerektiğidir; örneğin:

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

yardımcı bir türünü kullanarak I etrafında çalıştık yolu

: Onları ayrı türü, önlemek isteyen arasında

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

Ama çeşitli nedenlerle (ki ben olduğum şey zorlaştırıyor Yapıyordum, daha iyi bir çözümün var olduğunu umuyorum. Herhangi bir fikir?

+1

Standart argümanlar şey taklit değildir. Varsayılanlar sağlarlar. –

+3

Kayıt için, "Bir uzmanlığın şablon parametre listesi, varsayılan şablon argümanı değerleri içermemelidir" '[C++ 11: 14.5.5/8]' –

+0

@LightnessRacesinOrbit, bu sorunun yanlış olduğuna işaret etmek ister misiniz? C++ 11, ya da başka bir şey değişti? – ajg

cevap

3

Belki bir temel sınıf içine ayrımı sopa olabilir:

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 
}; 
İlgili konular