Ich habe eine Funktion, die ein variadisches Parameterpaket verwendet, und am Anfang möchte ich überprüfen, ob alle Elemente gleich sind. Kann ich die neuen C ++ 17-Falte-Ausdrücke irgendwie so prägnant als Einzeiler schreiben? Ich habe nachgedacht
%Vor% aber das funktioniert nicht, da es kompiliert, um zuerst die zwei letzten Argumente richtig zu vergleichen, aber dann vergleicht das drittletzte Argument mit dem Ergebnis des ersten Vergleichs, der ein bool ist. Welchen Anwendungsfall könnte diese Art von Faltenausdruck möglicherweise haben (ähnlich für args < ...
)? Gibt es eine Chance, die ich vermeiden kann, eine dedizierte rekursive Vorlage dafür zu schreiben?
Der Grund, warum das nicht funktioniert, liegt leider daran, dass boolesche Operatoren nicht wie in anderen Sprachen in C ++ ketten. Also der Ausdruck:
%Vor% (was Ihr Fold-Ausdruck erweitern würde) würde a
entweder mit true
oder false
vergleichen, nichts damit zu tun, was b
oder c
tatsächlich sind. Ich hatte gehofft, dass die operator<=>
eine Verkettung hinzufügen würde, aber anscheinend wurde dieser Teil gelöscht.
Die Fixes sind, dass Sie die Vergleiche auflösen müssen:
%Vor%Natürlich eignet sich das nicht zum Falten, aber man könnte stattdessen alles mit dem ersten Element vergleichen:
%Vor%Was soll ich sagen:
%Vor%An diesem Punkt müssen wir nur in der Lage sein, das erste Element herauszuziehen. Kein Problem, dafür sind Lambdas offensichtlich:
%Vor% Wie von Piotr Skotnicki vorgeschlagen, besteht eine einfache Lösung darin, das erste Argument von den folgenden zu trennen und es mit &&
als faltenem Operator
Zum Beispiel die folgende Funktion, die true
zurückgibt, wenn alle Argumente gleich
Leider funktioniert das nicht mit einer leeren Liste von Argumenten
%Vor% Sie können jedoch das spezielle leere Argument foo()
Wenn Sie aus irgendeinem Grund die args
in einer a0
und die folgende args
nicht teilen können?
Nun ... Sie können natürlich die vorhergehende Funktion foo()
(mit spezieller leerer Version) verwenden
oder Sie können den C ++ 17 falten Ausdruck mit Komma Operator und Zuweisung wie in der folgenden bar()
Beachten Sie die anfängliche Null in a0
Zuweisung, die die Verwendung dieser Lösung auch mit einer leeren Liste von Argumenten ermöglicht.
Leider bekomme ich von der vorhergehenden auto a0
Zuweisung eine Menge Warnungen ("Ausdrucksergebnis unbenutzt", von clang ++, und "linker Operand des Komma-Operators hat keinen Effekt", von g ++), dass ich nicht weiß wie zu vermeiden.
Das Folgende ist ein vollständiges funktionierendes Beispiel
%Vor%- BEARBEITEN -
Wie von dfri (danke!) gezeigt, für und leer args...
pack, die Werte für die folgenden gefalteten Ausdrücke
sind jeweils true
und false
.
So kann die Rückgabeanweisung von foo()
und bar()
gleichgültig geschrieben werden
oder
%Vor% und das gilt auch für den Fall sizeof...(args) == 0U
.
Aber ich vergesse diese Art von Details und bevorzuge explizit (mit dem letzten && true
) den Leerwert.
Tags und Links c++ templates variadic-templates c++17 fold-expression