2013-07-01 9 views
8

ho appena presentato this bug on Microsoft Connect per quanto riguarda l'impossibilità di compilare il seguente frammento giocattolo di codice:Visual C++ 12 (VS2013 Preview) modello variadic con parametro di funzione workaround

template <typename... P> struct S { 
    template <void(*F)(P...)> static void T() { } 
}; 

void A(int, float) { } 
int main() { S<int, float>::T<&A>(); } 

L'errore è:

test.cpp(2): error C3520: 'P' : parameter pack must be expanded in this context 

In sostanza, non posso decomprimere un tipo variadico all'interno di una firma di funzione quando viene usato come parametro template. Questo codice è (credo) legale; almeno GCC 4.7, Clang 3.0 e ICC 13 lo supportano.

Ho visto this SO question ma non è richiesta o fornita alcuna soluzione alternativa, che è ciò che sto cercando.

Anche se non è molto critico (ovviamente sono andato avanti senza modelli variadici per molti anni) questo modello è di particolare importanza per alcuni dei lavori che mi piacerebbe fare e alcuni articoli che mi piacerebbe fare sulle tecniche di riflessione in C++ 11 per serializzazione, binding di script, ecc. che è qualcosa che mi piacerebbe essere utile agli utenti di Visual Studio (essendo di gran lunga il set di strumenti per il compilatore dominante nel mio settore). Mi piacerebbe sperare che gli ingegneri di Microsoft saranno in grado di risolvere questo problema entro il 2013 RTM, ma non sto trattenendo il respiro.

Un giocattolo (a memoria questa volta) esempio di come questo viene utilizzato è qualcosa di simile (meno le macro che lo rendono un po 'più facile da usare):

Reflect<MyType>("MyType") 
.bind("GetMatrix", mat44, &MyType::GetMatrix>() 
.bind("Display", void, &MyType::Display>(); 

Naturalmente tutto questo può essere fatto senza modelli variadici. Ci vogliono solo grandi quantità di codice e accettare limitazioni alla massima aritmetica delle funzioni associate, naturalmente. E sì, il passaggio delle funzioni come parametro template è di importazione, a causa della natura di come funzionano i point pointer dei membri in Visual Studio (dimensioni variabili) e del desiderio di raggiungere l'efficienza alla pari con Impossibly Fast C++ Delegates (nella mia nicchia della comunità C++, questo livello di ottimizzazione a volte può davvero importare), che nega l'opzione di utilizzare std::function o disegni simili.

C'è un work-around per questo bug VS? O in un altro modo per utilizzare i modelli variadic per utilizzare un parametro del puntatore di funzione (in fase di compilazione) in VC++ 12?

risposta

6

Non so perché, ma la semplificazione con una typedef sembra funzionare:

template <typename... P> 
struct S 
{ 
    typedef void (*MyFunc)(P...); 

    template <MyFunc myFunc> 
    static void foo() {} 
}; 

void foo2(int, float) {} 

int main() 
{ 
    S<int, float>::foo<&foo2>(); 
} 

Almeno su Visual Studio 2013 ultimo Preview.

+0

Perfetto. Dovrò capire come applicarlo facilmente ai puntatori di funzioni dei membri vincolanti, ma dovrebbe essere una torta. –

Problemi correlati