Wenn SFINAE für einen beliebigen Typ ausgeführt wird, muss das Ergebnis eines Ausdrucks oft in void
umgewandelt werden. Ich habe zwei Möglichkeiten gesehen, dies zu tun; eine Besetzung zu void:
Oder alternativ den Kommaoperator mit einem void prvalue RHS verwenden:
%Vor% Es ist mein Verständnis, dass in beiden Fällen expr
ausgewertet wird (für Wohlgeformtheit in einem nicht evaluierten Kontext) und das Ergebnis (oder der Ergebnistyp in einem nicht evaluierten Kontext) verworfen wird; es ist in beiden Fällen nicht möglich, auch nur eine pathologische Klasse T
T::operator void()
oder operator,(T, void)
zu überschreiben. (Siehe: Warum wird "operator void" nicht mit der Cast-Syntax aufgerufen? ? , Was macht die Leere ( ) 'in' auto f (params) - & gt; decltype (..., void ()) 'tun? ).
Stimmt das, sind diese beiden Idiome gleichwertig, oder gibt es irgendwelche Umstände, unter denen man dem anderen vorgezogen werden sollte (möglicherweise mit Nicht-Standard-Compilern)? Wenn nicht, gibt es irgendwelche Gründe (z. B. Verständlichkeit), einander vorzuziehen?
Beide erfüllen die Anforderungen:
expr
als ausrangierter Wert gültig ist und nur das. void
ein (zur Verwendung in nachgestellten Rückgabetypen oder für teilweise Spezialisierungen ) Somit sind die Methoden äquivalent, wenn die obigen Kriterien berücksichtigt werden.
In diesem Sinne würde ich empfehlen, das zu verwenden, was in Ihrem Code prägnanter ist; aber was auch immer Sie wählen, halten Sie sich an die Konsistenz.
Man kann auch einen funktionalen Stil-Cast verwenden, da er per Definition der expliziten Cast-Notation entspricht, wenn nur ein Argument vorhanden ist - d. H.
funktioniert auch.
Der Unterschied ist im Grunde stilistisch.
In einigen Fällen kann die void()
-Form aufgrund des niedrigen Vorrangs des Komma-Operators ein zusätzliches Klammerpaar vermeiden. Zum Beispiel, foo + bar, void()
funktioniert gut, aber (void) (foo + bar)
(oder das funktionale Format gleichwertig) müssen den gesamten Ausdruck in Klammern setzen.
In anderen Fällen ist die Verwendung von (void)
cast möglicherweise prägnanter. Um beispielsweise vor überlasteten Kommas in ++it1, ++it2, ++it3
zu schützen, können Sie ein (void)
cast - ++it1, (void) ++it2, ++it3
verwenden, aber um void()
zu verwenden, müssten Sie es zweimal schreiben: ++it1, void(), ++it2, void(), ++it3
.