2010-11-27 4 views
0

テンプレートテンプレートパラメータを渡す際に、そのパラメータが前のテンプレートパラメータのサブタイプと等しい型の非型の値である読んでいると言うと難しいです!)、そして、私は、単一のパラメータ化されたテンプレートで結果を結合しようとした後、いくつかのビルドエラーを抱えています。両方のメンバがパラメータ化された後にのみ、テンプレートテンプレートパラメータでエラーを作成する

私は(G ++ 4.4.1でうまくコンパイルし、-std = C++ 0xの)次のコードを持っている:

#include <iostream> 

using namespace std; 

enum class Labels { A , B }; 

template <Labels L> 
struct LabelTypeMap { 
typedef int type_t; 
}; 

template<> struct LabelTypeMap<Labels::B> { typedef double type_t; }; 

template <bool Enable=true> 
struct Hold 
{ 
typedef Labels enum_t; 
}; 

template <> 
struct Hold<true> 
{ 
typedef Labels enum_t; 
}; 

template< typename Holder , template< typename Holder::enum_t > class typeMap , bool Enable > 
struct Whatever 
{ 
template < typename Holder::enum_t label > 
void Operate(typename typeMap<label>::type_t parameter) {}; 
}; 

template< typename Holder , template< typename Holder::enum_t > class typeMap > 
struct Whatever< Holder , typeMap , true > : public Holder 
{ 
template < typename Holder::enum_t label > 
void Operate(typename typeMap<label>::type_t parameter) { cout << "operate on " << parameter << endl; }; 
}; 

template < bool Enable > 
struct Now { 
typedef Hold<true> MyHold; // <----- check this out! 
typedef Whatever< MyHold , LabelTypeMap , Enable > concrete_t; 
}; 

int main() { 
Now<true>::concrete_t obj; 
obj.Operate<Labels::A>(3.222222222222222222222); 
obj.Operate<Labels::B>(3.2222222222222222222); 
}; 

しかし、今、Nowテンプレートを見て:私は2人のメンバーを持っているがブール値によってパラメータ化されています。 concrete_tは、Nowテンプレートのboolパラメータに依存しますが、MyHoldではありません。私はそれを変更したいので、私はこの1とNow宣言置き換える:

template < bool Enable > 
struct Now { 
typedef Hold<Enable> MyHold; // <----- boom! 
typedef Whatever< MyHold , LabelTypeMap , Enable > concrete_t; 
}; 

をしかし、これは私に次のエラーを与える:

error: type/value mismatch at argument 2 in template parameter list for ‘template<class Holder, template<typename Holder::enum_t <anonymous> > class typeMap, bool Enable> struct Whatever’ 
error: expected a template of type ‘template<typename Holder::enum_t <anonymous> > class typeMap’, got ‘template<Labels L> struct LabelTypeMap’ 

私はこれで十分な長見つめていると私は言わなければなりませんなぜこの単純な変更がエラーを引き起こすのか、私は完全に理解できません。何か案は?

EDIT:はここに問題の最小限の博覧会です(たぶん)、それが簡単に熟考します

:誰かが混乱を把握できるようになるまで、ここで
$ cat templatetemplate.cc 
template <int i> 
struct LabelTypeMap { typedef int type_t; }; 

template <bool> 
struct Hold { typedef int type; }; 

template<typename Holder, template<typename Holder::type> class typeMap> 
struct Whatever { }; 

template <bool Enable> 
struct Now { typedef Whatever<Hold<ENABLE>, LabelTypeMap> concrete_t; }; 

Now<true>::concrete_t obj; 

$ g++ -DENABLE=Enable -c templatetemplate.cc 
templatetemplate.cc:11: error: type/value mismatch at argument 2 in template parameter list for ‘template<class Holder, template<typename Holder::type <anonymous> > class typeMap> struct Whatever’ 
templatetemplate.cc:11: error: expected a template of type ↵ 
    ‘template<typename Holder::type <anonymous> > class typeMap’, got ↵ 
    ‘template<int i> struct LabelTypeMap’ 
[email protected]:~/play$ 
$ g++ -DENABLE=true -c templatetemplate.cc 
(no error) 
+0

C++ 0xとの接続は何ですか?ああ、それを見つけました: 'enum class'。 –

+0

実際に関連しているかどうかわかるまでタグを削除しました。おそらくそれは – lurscher

+0

ではありません(少なくとも 'enum class'については、それは問題ではありませんが) – icecrime

答えて

1

が回避策コンパイルします
template < bool Enable > 
struct Now; 

template <> 
struct Now<false> { 
    typedef Hold<false> MyHold; 
    typedef Whatever< MyHold , LabelTypeMap , false > concrete_t; 
}; 

template <> 
struct Now<true> { 
    typedef Hold<true> MyHold; 
    typedef Whatever< MyHold , LabelTypeMap , true > concrete_t; 
}; 
+0

+1テストケースを短くする – lurscher

関連する問題