2013-07-01 10 views
8

I this bug on Microsoft Connect über die Unfähigkeit, nur reichte die folgenden Spielzeug-Snippet-Code zu kompilieren:Visual C++ 12 (VS2013 Preview) variadische Vorlage mit Funktionsparameter Abhilfe

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

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

Der Fehler ist:

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

Im Wesentlichen kann ich einen variadic Typ innerhalb einer Funktionssignatur nicht entpacken, wenn er als ein Schablonenparameter benutzt wird. Dieser Code ist (glaube ich) legal; zumindest unterstützen GCC 4.7, Clang 3.0 und ICC 13 alles.

Ich habe gesehen this SO question, aber keine Problemumgehungen angefordert oder gegeben, was ich suche.

Obwohl nicht superkritisch (offensichtlich komme ich seit vielen Jahren ohne variadische Vorlagen aus) ist dieses Muster von besonderer Bedeutung für einige der Arbeiten, die ich gerne machen würde und einige Artikel, die ich gerne machen würde auf C++ 11-Reflektionstechniken für Serialisierung, Skriptbindung usw., was ich gerne für Visual Studio-Benutzer verwenden würde (da es bei weitem das dominierende Compiler-Toolset in meiner Branche ist). Ich würde gerne hoffen, dass die Microsoft-Ingenieure dies bis 2013 RTM beheben können, aber ich halte nicht den Atem an.

Ein Spielzeug (aus dem Gedächtnis dieser Zeit) Probe, wie diese verwendet wird, ist so etwas wie (minus die Makros, die es etwas einfacher zu bedienen):

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

Natürlich ist dies alles getan werden kann, ohne variadische Vorlagen. Es erfordert natürlich große Mengen an Code und akzeptiert Beschränkungen für die maximale Funktionalität von gebundenen Elementfunktionen. Und ja, die Übergabe der Funktionen als Template-Parameter ist aufgrund der Art, wie Memberfunktionszeiger in Visual Studio arbeiten (variable Größe) und des Wunsches nach Effizienz auf Augenhöhe mit Impossibly Fast C++ Delegates (in meiner Nische der C++ - Community) Diese Ebene der Optimierung kann manchmal tatsächlich wichtig), die die Option der Verwendung std::function oder ähnliche Designs negiert.

Gibt es einen Workaround für diesen VS-Fehler? Oder eine andere Möglichkeit, variadische Vorlagen zu verwenden, um einen (Kompilierzeit-) Funktionszeiger in VC++ 12 zu verwenden?

Antwort

6

nicht sicher, warum, aber mit einem typedef Vereinfachung scheint zu funktionieren:

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>(); 
} 

Mindestens auf dem Visual Studio 2013 Ultimative Vorschau.

+0

Perfekt. Ich muss herausfinden, wie man das leicht auf die Bindeglied-Funktionszeiger anwendet, aber das sollte Kuchen sein. –

Verwandte Themen