2014-07-25 8 views
7

Ich habe eine Frage, die funktionale Vorlagenargumente zu Vorlagenklassen in C++ enthält.Auspacken von Argumenten eines Funktionsparameters an eine C++ - Vorlagenklasse

Ich möchte ein Template-Klasse Foo nehmen einen einzelnen Template-Parameter Fun

template <typename Fun> 
    struct Foo { 
     ... 
    }; 

definieren, so dass eine Funktion, wie

gegeben
void bar(std::string a, float b, char c) 
    { 
     ... 
    } 

dann Foo<bar>::args_t für

auf ein typedef äquivalent
std::tuple<std::string, float, char> 

Ist dies p Möglich? (Die Verwendung von std::tuple hier ist nur für Konkretheit. Allgemein frage ich mich, ob es möglich ist, so etwas wie Muster-Matching auf die Argumente eines funktionalen Template-Parameters zu tun.)

Der Punkt ist zu vermeiden, Foo zu definieren in eine Weise, wie

template Foo<typename A, typename B, typename C, typename D, 
     D (*Fun)(A a, B b, C c)> 
    struct Foo { 
     typedef std::tuple<A,B,C> args_t; 
    }; 

die sowohl Festlegung an eine festen Anzahl von Funktionsargumenten erfordert, und erfordern das Argument und Rückgabetypen der Funktion explizit als Template-Parameter zur Verfügung gestellt werden. (Das Definieren von Foo mit variadischen Vorlagen könnte vermutlich das frühere Problem lösen, aber was ist mit letzterem?)

Vielen Dank!

+0

Blick in variadische Vorlagen. Sie sollten auch vermeiden, Typen mit '_t 'zu benennen, da diese in POSIX reserviert sind. – user657267

+1

@ user657267 Ich bin mir ziemlich bewusst variadic Vorlagen, und erwähnte sie in meiner Frage. Der Kommentar zu Benennungsarten mit '_t' scheint etwas außerhalb des linken Feldes zu liegen. – factotum

+0

Deshalb ist es ein Kommentar und keine Antwort. – user657267

Antwort

11

Deklarieren Sie eine primäre Vorlage, und lassen Sie sie nicht implementiert.

template<typename T> 
struct foo;  // unimplemented primary template 

Geben Sie dann eine teilweise Spezialisierung an, die den Funktionstypen als Vorlageargument entspricht.

template<typename Result, typename... Args> 
struct foo<Result(Args...)> 
{ 
    using args_t = std::tuple<Args...>; 
}; 

Sie können die verschachtelten Typ Zugriff als

foo<decltype(bar)>::args_t 

Live demo

+0

Großartig, decltype scheint hier der Schlüssel zu sein, vielen Dank! – factotum

Verwandte Themen