2011-01-21 13 views
8

Ho un modello di classe e non riesco a capire come eseguire un'istanza di stile Variadic Template.VS2010 Esempio di modello variadico C++

Ecco il "codice" finora di quello che sto cercando:

template<typename _Classname, typename... Args> 
class CFunctorStartExT 
{ 
    friend class CXXFactory; 
protected: 
    template<typename U> 
    CFunctorStartExT(typename U& _functor, Args&... args) : 
    m_Functor(_functor), 
    m_args(args) 
    { 
    } 
    virtual bool ProcessLoop(CSomeClass* pThread) 
    { 
    return m_Functor(pThread, m_args); 
    } 

protected: 
    _Classname& m_Functor; 
    Args... m_args; 
}; 

Ovviamente questo non compilerà :). L'idea è di creare una classe in grado di memorizzare i valori passati (se ce ne sono ... potrebbe avere solo _Classname/U definiti) sul costruttore in modo che possano essere recuperati in seguito per passare a m_Functor in un'altra funzione.

Primo: è possibile eseguire il modello Variadic in VS2010? Ricevo problemi di compilazione solo con la dichiarazione modello error C2143: syntax error : missing ',' before '...' dalla riga template<typename _Classname, typename... Args>

In secondo luogo, è possibile eseguire ciò che sto cercando di realizzare? Grazie!

+2

I nomi che iniziano con un trattino basso seguito da una lettera maiuscola, come '_Classname', sono riservati e non è necessario utilizzarli nel programma. –

+0

oh .. riservato per cosa/chi? Ho provato a cambiare la mia convenzione di denominazione .. (cambia da m_, g_, ecc.) – BabelFish

+1

Vedi [this] (http://stackoverflow.com/questions/228783/what-are-the-rules-about-using -un-sottolineatura-in-ac-identifier). – GManNickG

risposta

24

Visual C++ 2010 non supporta i modelli variadic.

+0

lol .. bummer .. :(ad ogni modo per realizzare quello che sto facendo tramite macro variadic? So che std :: make_shared ha uno stile variadico ma mi perdo in tutti i parametri. – BabelFish

+3

Significa che qualcuno in Microsoft ha fatto un sacco di copia e incolla per ottenere una [classe di tuple] limitata (http://msdn.microsoft.com/en-us/library/bb982837.aspx)? – Thomas

+1

no .. hanno questa macro molto complessa definire "meccanismo" che definisce e non definisce per creare le classi necessarie .. da quello che posso dire lo si vede nei file xxshared e xfwrap e xfwrap1 ecc. – BabelFish

-2

I modelli di Variadic sono una patch su un kludge su un hack: non ti piacerà questo. Il modo per farlo (in cima alla mia testa) è utilizzare la specializzazione del modello insieme all'ereditarietà. Qualcosa in questo senso:

template<typename Classname, typename... Args> 
class CFunctorStartExT; 

template<typename Classname, typename Arg0, typename... Args> 
class CFunctorStartExT : private CFunctorStartExT<Classname, Args...> { 
protected: 
    Arg0 m_arg; 
}; 

template<typename Classname> 
class CFunctorStartExT { 
protected: 
    Classname &m_Functor; 
}; 

non l'ho mai fatto prima, e non hanno provato, ma questa è l'idea generale. Potresti dare un'occhiata all'implementazione di std::tuple per qualcosa che funziona davvero.

3

Credo che quanto segue farà quello che vuoi. In primo luogo è necessario un programma di utilità:

// make_tuple_indices 

template <size_t...> struct tuple_indices {}; 

template <size_t _Sp, class _IntTuple, size_t _Ep> 
struct make_indices_imp; 

template <size_t _Sp, size_t ..._Indices, size_t _Ep> 
struct make_indices_imp<_Sp, tuple_indices<_Indices...>, _Ep> 
{ 
    typedef typename make_indices_imp<_Sp+1, tuple_indices<_Indices..., _Sp>, _Ep>::type type; 
}; 

template <size_t _Ep, size_t ..._Indices> 
struct make_indices_imp<_Ep, tuple_indices<_Indices...>, _Ep> 
{ 
    typedef tuple_indices<_Indices...> type; 
}; 

template <size_t _Ep, size_t _Sp = 0> 
struct make_tuple_indices 
{ 
    static_assert(_Sp <= _Ep, "make_tuple_indices input error"); 
    typedef typename make_indices_imp<_Sp, tuple_indices<>, _Ep>::type type; 
}; 

quindi è possibile utilizzare questo per aiutare a espandere una tupla tenendo le argomentazioni:

template<typename _Classname, typename... Args> 
class CFunctorStartExT 
{ 
    friend class CXXFactory; 
protected: 
    template<typename U> 
    CFunctorStartExT(U& _functor, Args&... args) : 
    m_Functor(_functor), 
    m_args(args...) 
    { 
    } 

    virtual bool ProcessLoop(CSomeClass* pThread) 
    { 
    return ProcessLoop(pThread, 
         typename make_tuple_indices<sizeof...(Args)>::type()); 
    } 

protected: 
    _Classname& m_Functor; 
    std::tuple<Args...> m_args; 

private: 
    template <std::size_t ...Indx> 
    bool ProcessLoop(CSomeClass* pThread, tuple_indices<Indx...>) 
    { 
     return m_Functor(pThread, std::get<Indx>(m_args)...); 
    } 
}; 

quanto riguarda il sostegno modello variadic VS2010: Non ne ho idea.

+0

Benvenuti in Stack Overflow! –

+2

questo sarebbe bello se VS2010 potesse supportare "typename. .. " – BabelFish

+0

Grazie a questo ho risolto uno scenario abbastanza simile con il quale avevo bisogno di aiuto. Va bene includere il codice tuple_indices/make_tuple_indices in una libreria con licenza simile al MIT? La licenza può essere vista qui: http://www.angelcode.com/angelscript/sdk/docs/manual/doc_license.html – Functastic

Problemi correlati