Subscribed unsubscribe Subscribe Subscribe

LokiのGenScatterHierarchyを継承して使う

Lokiのタイプリストを使ったGenScatterHierarchyというやつは結構面白いんですが,それを継承したクラスでFieldヘルパを使おうとすると(VS2010では)コンパイルが通らない.

template <class T>
struct Foo
{
    std::vector<T> value_;
};

template <class TList>
class Bar : public Loki::GenScatterHierarchy<TList, Foo>
{
public:
    template<int i, class T>
    void push(T value){
        Loki::Field<i>(*this).value_.push_back(value);
    }
};

int main(void) {
    
    Bar< TYPELIST_5( int, int, double, double, std::string ) > list;
    list.push<0>(5);//最初のintに5をpushしたい
}
error C2594: '初期化中' : 'Bar<TList>' から 'Loki::GenScatterHierarchy<AtomicType,Unit> &' への変換はあいまいです。

基底クラスにLeftBaseがいっぱい有るぞ!どういうこっちゃ!っていう事らしい.単純に,GenScatterHierarchyにint型のテンプレート引数を追加してみる.

template <class TList, template <class> class Unit, unsigned int Idx=0>
class GenScatterHierarchy;

template <class T1, class T2, template <class> class Unit, unsigned int Idx>
class GenScatterHierarchy<Typelist<T1, T2>, Unit,Idx>
	: public GenScatterHierarchy<T1, Unit, Idx>
	, public GenScatterHierarchy<T2, Unit, Idx+1>
{
public:
	typedef Typelist<T1, T2> TList;
	typedef GenScatterHierarchy<T1, Unit, Idx> LeftBase;
	typedef GenScatterHierarchy<T2, Unit, Idx+1> RightBase;
	template <typename T> struct Rebind
	{
		typedef Unit<T> Result;
	};
};

template <class AtomicType, template <class> class Unit, unsigned int Idx>
class GenScatterHierarchy : public Unit<AtomicType>
{
	typedef Unit<AtomicType> LeftBase;
	template <typename T> struct Rebind
	{
		typedef Unit<T> Result;
	};
};

template <template <class> class Unit, unsigned int Idx>
class GenScatterHierarchy<NullType, Unit, Idx>
{
	template <typename T> struct Rebind
	{
		typedef Unit<T> Result;
	};
};

こうすると左から順にGenScatterHierarchy, GenScatterHierarchy, GenScatterHierarchy...というやつらが作られていき,曖昧さは無くなりました.めでたし.

参考:reoccuring types in a Loki::Tulpe - comp.lang.c++.moderated