2009-07-16 9 views
1

Ich versuche eine Liste von Argumenten zu initialisieren, die mit fusion :: invoke verwendet werden sollen. Die args sind alle Form:Wie man über eine boost :: fusion sequenz iteriert?

template <typename Type> 
struct ArgWrapper 
{ 
    inline ArgWrapper(){} 
    inline void Setup(lua_State*L,int idx) 
    { 
     //setup this value from the lua state... 
     //in reality this class is specialised for different lua types 
    } 
    operator Type(){return value;} 
    Type value; 
}; 

So kann ich zum Beispiel

int add(int a,int b){return a+b;} 
fusion::vector<ArgsWrapper<int>,ArgsWrapper<int> > v; 
fusion::at_c<0>(v).value=1; 
fusion::at_c<1>(v).value=2; 
std::cout<<fusion::invoke(add,v)//prints 3 

Aber wenn ich eine Fusionssequenz vom Typ FusionListType haben, wo ich jede Art in der Folge wissen ist ein ArgWrapper eines Typs, wie kann ich durch diese Liste iterieren und die Setup-Funktion für jedes Element aufrufen (Ich habe nur einen Lua_State-Zeiger und möchte es als erstes Argument für Setup verwenden, und ich möchte die Position in der Sequenz verwenden als zweites Argument).

Also für einen Vektor der Größe 3 Ich möchte die resultierende Logik sein:

lua_State*L; 
fusion::at_c<0>.Setup(L,1); 
fusion::at_c<1>.Setup(L,2); 
fusion::at_c<2>.Setup(L,3); 

ich versucht habe:

template<typename ArgWrapperType,int N> 
void FillArgWrapper(ArgWrapperType arg,lua_State*L) 
{ 
    fusion::at_c<N>(arg).Setup(L,N+1); 
} 
template<typename ArgWrapperType> 
void FillArgWrapper<ArgWrapperType,0>(ArgWrapperType arg,lua_State*L) 
{ 
    fusion::at_c<0>(arg).Setup(L,1); 
} 

Aber um dies zu kompilieren fehlschlägt, function template partial specialisation ‘FillArgWrapper<ArgWrapperType, 0>’ is not allowed sagen.

Vielen Dank im Voraus.

Antwort

4

Ok, ich habe es herausgefunden. Ich muss eine Struktur verwenden:

template <typename ArgWrapperList,u32 N=mpl::size<ArgWrapperList>::value-1> 
struct ArgWrapperListFiller 
{ 
    static inline void Setup(ArgWrapperList &args,lua_State*L) 
    { 
     fusion::at_c<N>(args).Setup(L,N+1); 
     ArgWrapperListFiller<ArgWrapperList,N-1>::Setup(args,L); 
    } 
}; 
template <typename ArgWrapperList> //base case, do not recurse 
struct ArgWrapperListFiller<ArgWrapperList,0> 
{ 
    static inline void Fill(ArgWrapperList &args,lua_State*L) 
    { 
     fusion::at_c<0>(args).Setup(L,1); 
    }; 
};