2012-03-15 15 views
5

デフォルトのテンプレート引数を使用して、テンプレート宣言の複合型式のエイリアスをシミュレートできます。たとえば:部分的な特殊化でデフォルトのテンプレート引数をシミュレートすることは可能ですか?

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

しかし、部分的な特殊化は、デフォルトのテンプレート引数([C++11: 14.5.5/8])を持っていないかもしれないので、このトリックは動作しません。なぜ体内のtypedefがうまくいかないのか自分に尋ねるかもしれません。その答えは条件付き有効化を行うためにエイリアスがクラス本体の前にスコープ内にある必要があるということです。例えば:

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

しかし、別の種類を回避したいというその中で様々な理由(のために、私は何を複雑に:私はそれを中心に働いてきた

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

方法は、補助タイプを使用しています)、私はより良い解決策が存在することを望んでいます。何か案は?

+1

デフォルトの引数は何かをシミュレートしません。彼らはデフォルトを提供します。 –

+3

"専門分野のテンプレートパラメータリストには、デフォルトのテンプレート引数値が含まれていないはずです。" [C++ 11:14.5.5/8] ' –

+0

@LightnessRacesinOrbit、この問題はないと指摘していますか? C++ 11で変更されましたか? – ajg

答えて

3

たぶん、あなたは、基本クラスに区別を固執することができます:

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 
}; 
関連する問題