C
GmbH schrieb:
Schade das dies im aktuellen Standard wohl nicht geht.
Jedenfalls nicht ohne einigen Schreibaufwand, wobei man mit boosts preprocessor-Bibliothek wahrscheinlich viel einsparen kann - auf Kosten der Lesbarkeit: Man könnte für jeden Fall N=0,1,... des Funktionstyps mit N Parametern spezialisieren:
template<typename T> class foo;
template<typename R> class foo< R() >;
template<typename R, typename P1> class foo< R (P1) >;
template<typename R, typename P1, typename P2> class foo< R (P1,P2) >;
template<typename R, typename P1, typename P2, typename P3> class foo< R (P1,P2,P3) >;
template<typename R, typename P1, typename P2, typename P3, typename P4> class foo< R (P1,P2,P3,P4) >;
// usw.
Dabei muss es nicht unbedingt notwendig sein, das gesamte Template zu spezialisieren, wenn der Unterschied nur bei Memberfunktionen besteht, könnte man die Spezialisierung, resp. Überladung auch an dieser Stelle durchführen, ggf. Unterstützung durch SFINAE per enable_if.
Ansonsten hilft tatsächlich nur das Warten auf den nächsten Standard oder, wenn es noch nicht Produktionscode sein muss, kann man auch mit g++ 4.3 experimientieren:
template<typename T> class foo;
template<typename R, typename ... P> class foo< R (P...) >;
// usw.
Was leider auch im nächsten Standard nicht möglich sein wird, ist eine derartige Flexibilität mit anderen Dingen als Typen zu ermöglichen. Mir würde zum Beispiel so ein einfacher "Funktorisierer" gefallen (Funktionen schreiben ist nun mal bequemer):
template<auto /* meine Erfindung: soll jedes beliebige non-type-Argument akzeptieren */> struct Functor;
template<typename R, typename ... P> struct Functor< R (*F)(P...) >
{
typedef R result_type;
template<typename ... Args>
R operator()(Args&&... args) const
{
return F( std::forward< Args >( args ) ... );
}
};
Sehr viele Templates, die mit non-type-Parametern arbeiten, haben die Form
template<typename T, T x> ...
Dabei wäre die explizite Nennung des Typs eigentlich überflüssig - die notwendigen Mechanismen zur Typdeduktion besitzt der Compiler sowieso.