Ich habe eine Traits-Klasse geschrieben, die mir Informationen über die Argumente und den Typ einer Funktion oder eines Funktionsobjekts in C++ 0x extrahiert (getestet mit gcc 4.5.0) . Der allgemeine Fall behandelt Funktionsobjekte:Spezialisierung einer Vorlage auf ein Lambda in C++ 0x
template <typename F>
struct function_traits {
template <typename R, typename... A>
struct _internal { };
template <typename R, typename... A>
struct _internal<R (F::*)(A...)> {
// ...
};
typedef typename _internal<decltype(&F::operator())>::<<nested types go here>>;
};
Dann habe ich eine Spezialisierung für Normalfunktionen in globalen Bereichen:
template <typename R, typename... A>
struct function_traits<R (*)(A...)> {
// ...
};
Dies funktioniert gut, ich habe eine Funktion in die Vorlage oder ein Funktionsobjekt passieren kann und es funktioniert:
template <typename F>
void foo(F f) {
typename function_traits<F>::whatever ...;
}
int f(int x) { ... }
foo(f);
Was, wenn statt eine Funktion oder ein Funktionsobjekt in foo
von vorbei, ich einen Lambda-Ausdruck übergeben möge?
foo([](int x) { ... });
Das Problem hier ist, dass keine Spezialisierung von function_traits<>
gilt. Der C++ 0x-Entwurf besagt, dass der Typ des Ausdrucks ein "eindeutiger unbenannter Klassentyp ohne Union" ist. Das Entwirren des Ergebnisses des Aufrufs von typeid(...).name()
für den Ausdruck gibt mir die scheinbar interne GCC-Namenskonvention für das Lambda main::{lambda(int)#1}
, nicht etwas, das syntaktisch einen C++ - Typnamen darstellt.
Kurz gesagt, ist es etwas, was ich in die Vorlage auszureizen:
template <typename R, typename... A>
struct function_traits<????> { ... }
, die diese Züge Klasse ermöglicht einen Lambda-Ausdruck zu akzeptieren?
Nein. Warum denken Sie, dass Sie so etwas brauchen? – sellibitze
Ich dachte mein Beispiel gab einen anständigen Anwendungsfall: Wenn ich einen generischen Algorithmus habe, der ein Funktions- oder Funktionsobjekt aufnimmt, kann ich diese Merkmalsklasse verwenden, um nicht nur den Rückgabetyp zu bestimmen (was heutzutage auch mit declty möglich wäre), aber auch die Arten der Argumente. (Ich habe den Großteil des Codes weggelassen, um zu verhindern, dass der Post zu lang wird.) Da ich ein Funktions- oder Funktionsobjekt übergeben kann, möchte ich für Orthogonalitätszwecke auch ein Lambda übergeben können. Dies ist alles eine akademische Übung, die aus dem Lesen von "Elements of Programming" entstand. –
@Tony: Die Antwort ist ja, ich habe es getan. Ich werde aber ein wenig später auf diese Frage zurückkommen können. Welche Eigenschaften willst du bekommen? – GManNickG