Prüfe, ob alle Elemente mit dem C ++ 17-Falzausdruck übereinstimmen

7

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?

    
Tobias Brüll 18.10.2017, 08:53
quelle

2 Antworten

15

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%     
Barry 18.10.2017, 12:10
quelle
5

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

zu überprüfen

Zum Beispiel die folgende Funktion, die true zurückgibt, wenn alle Argumente gleich

sind %Vor%

Leider funktioniert das nicht mit einer leeren Liste von Argumenten

%Vor%

Sie können jedoch das spezielle leere Argument foo()

hinzufügen %Vor%

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

%Vor%

oder Sie können den C ++ 17 falten Ausdruck mit Komma Operator und Zuweisung wie in der folgenden bar()

verwenden %Vor%

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

%Vor%

sind jeweils true und false .

So kann die Rückgabeanweisung von foo() und bar() gleichgültig geschrieben werden

%Vor%

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.

    
max66 18.10.2017 10:17
quelle