Ihre Version funktioniert nicht mit z. Zeiger auf Mitglieder.Eine näher, aber noch nicht genaue Version wäre:
template <class F, class... Args>
auto async(F&& f, Args&&... args)
-> future<decltype(ref(f)(forward<Args>(args)...))>;
Der einzige Unterschied verbleibende mit std::result_of
ist, dass dies den Funktors als L-Wert (ein Problem, Ihre Version auch Aktien) weiterleitet. Mit anderen Worten, das Ergebnis eines solchen Anrufs (über eine std::reference_wrapper<F>
) ist typename std::result_of<F&(Args...)>::type
.
Dies ist eine schwierige Situation, in der mehrere Komponenten der Standardbibliothek (nur einige zu nennen, zusätzlich zu denen, die wir gerade erlebt haben: std::thread
, std::bind
, std::function
) werden im Hinblick auf eine schwer fassbare INVOKE (f angegeben, a0, a1, ..., aN) Pseudo-Ausdruck, der nicht genau f(a0, a1, ... aN)
entspricht. Da std::result_of
eine dieser Komponenten ist, und dient in der Tat, um den Ergebnistyp INVOKE zu berechnen, das ist die Diskrepanz, die Sie bemerken.
Da es keine std::invoke
gibt, die in Tandem mit dem Typ std::result_of
Typ Eigenschaft kommt, bin ich der Meinung, dass letzteres nur nützlich ist, um z. die Rückgabetypen der relevanten Komponenten der Standardbibliothek, wenn Ihr Code sie aufruft Wenn Sie eine prägnante und selbstdokumentierende Schreibweise wünschen, z. Ich empfehle Ihnen, Ihren eigenen Aliasnamen schreiben einen Rückgabetyp (ein sehr lohnendes Ziel für die Lesbarkeit, im Vergleich zu decltype
überall Beregnung), dann gilt:
template<typename F, typename... A>
using ResultOf = decltype(std::declval<F>()(std::declval<A>()...));
(Wenn Sie wollen, dass der Alias als ResultOf<F(A...)>
statt ResultOf<F, A...>
verwendet werden dann Sie benötigen ein wenig Maschine, um Muster über die Funktionssignatur zu passen.)
Ein zusätzlicher Vorteil dieses Alias ist, dass es SFINAE freundlich ist, im Gegensatz zu std::result_of
. Ja, das ist ein weiterer Fehler. (Um fair zu sein, obwohl dies für den kommenden Standard geändert wurde und die Implementierungen folgen bereits.)
Sie würden nichts verpassen, wenn Sie solch ein Merkmal verwenden, weil Sie Zeiger auf Mitglieder dank std::mem_fn
anpassen können.
Ist _especified_ oder _implemented_ mit 'result_of'? Denn das könnte nur eine Laune desjenigen sein, der es implementiert hat, oder es könnte implementiert worden sein, bevor 'declltype' es in den Zielcompiler geschafft hat. In Apples libC++ verwendet es keines von beiden. – zneak
@zneak: Die Deklaration, die ich gezeigt habe, wurde aus dem Standard kopiert, also wird 'std :: async' über' result_of' spezifiziert. Implementierungen können tun, was sie wollen, solange das von ihnen bereitgestellte Verhalten mit dem übereinstimmt, was angegeben ist. – KnowItAllWannabe
Wissen Sie einfach, dass es einige unglückliche Auswirkungen auf die Syntax "std :: result_of" gibt (http://stackoverflow.com/a/15489789/500104). – Xeo