Seite 1 von 1

structured binding vs. iterator pair

Verfasst: 23.05.2018, 05:31
von DerAlbi
Hallo Leute,
ich habe folgenden Code:

Code: Alles auswählen

const float HalfMin = *std::min_element(RawProjSensorValues_Half.begin(), RawProjSensorValues_Half.end());
const float HalfMax = *std::max_element(RawProjSensorValues_Half.begin(), RawProjSensorValues_Half.end());
Um endlich mich mehr auf C++17 einzulassen [und auch weil es ein effizienterer Algorithmus ist] möchte ich das auf minmax_element umstellen.

Code: Alles auswählen

const auto [HalfMin, HalfMax] = std::minmax_element(RawProjSensorValues_Half.begin(), RawProjSensorValues_Half.end());
Problem: minmax_element gibt ein pair von Iteratoren zurück. Man müsste die also irgendwie implizit dereferenzieren. Geht sowas in einem structured binding irgendwie?
Alle Lösungen erscheinen hässlich, da sie eine Zwischenvariable benötigen und den Rückgabewert von minmax_element explizit auseinander nehmen..

Code: Alles auswählen

auto HalfMinMax = std::minmax_element(RawProjSensorValues_Half.begin(), RawProjSensorValues_Half.end());
const float HalfMin = *HalfMinMax.first;
const float HalfMax = *HalfMinMax.second;
Man kann jetzt aber auch mit der neuen Variable structured bindings nutzen:

Code: Alles auswählen

auto HalfMinMax = std::minmax_element(RawProjSensorValues_Half.begin(), RawProjSensorValues_Half.end());
const auto [HalfMin, HalfMax] = std::tuple{*HalfMinMax.first, *HalfMinMax.second}; //std::pair geht auch
Egal wie, mir erscheint das alles eine Zeile zu viel zu sein. Hmmh. Die Tatsache, dass da Iteratoren rauspurzeln scheint irgendwie für Inkompatibilät zu sorgen :-(

Wer kurz mit der Situation rumspielen möchte: habe hier ein interaktives Beispiel vorbereitet: https://godbolt.org/g/88PS3K

Re: structured binding vs. iterator pair

Verfasst: 23.05.2018, 18:54
von dot
Woran genau scheitert es? https://godbolt.org/g/beYjDg

Re: structured binding vs. iterator pair

Verfasst: 23.05.2018, 19:35
von DerAlbi
Ok, diese Offensichtlichkeit hatte ich aus meinem Kopf komplett verbannt, da ich mit den Werten doch einiges Zeugs ausrechne und gerade in Formeln mit Multiplikation wirds irgendwann wirr.
Ich finde es halt irgendwie komisch.. das ist ein recht offensichtlicher Defekt bei dem structured bindings, wo ich mir nicht vorstellen kann, dass der nie bedacht wurde. Ich finde leider überhaupt nichts bei google, wo sowas mal diskutiert wurde oder gar Lösungen für diese Unannehmlichkeit. Da das Feature zumindest auf der CppCon recht gefeiert wurde kann ich mir nicht vorstellen, dass damit andere nicht zu kämpfen haben.

Re: structured binding vs. iterator pair

Verfasst: 23.05.2018, 19:54
von dot
Mir ist nicht ganz klar, wo genau du hier einen Defekt siehst. Die Funktion returned ein std::pair aus Iteratoren. Ein Structured Binding erlaubt dir, die beiden Elemente des std::pair, welche Iteratoren sind, an separate lokale Variablen zu binden...!?

Edit: btw https://godbolt.org/g/Px52qz

Re: structured binding vs. iterator pair

Verfasst: 23.05.2018, 21:16
von DerAlbi
Naja der Defekt ist mMn das man in structured bindings nicht dereferenzieren kann, sodass man - gerade bei trivialen oder mathematischen Typen - direkt mit den Werten arbeiten. Das kann man jetzt entweder auf die structured bindings schieben, dass dort Syntaktischer Zucker in den Klammern fehlt, oder auf minmax, wo Iteratoren anstatt z.B. Referenzen rauskommen. im Prinzip ist dein letzter Code-Vorschlag exakt das, was ich haben will. Dieser extra Umweg ist halt irgendwie merkwürdig. Ich finde es aber etwas kompliziert, wie du das machst ;-) Wenn man den Typ schon als pair benennt kann man ihn auch direkt nutzen https://godbolt.org/g/WD3CBo
Aber ja, diese Art Syntax hätte ich irgendwie implizit erwartet - wie gesagt, irgendwas kryptisches in den Eckigen Klammer vielleicht..

kannst du mir sagen, warum du in deinem Beispiel bei begin(..) und end(..) kein std:: davor schreiben musst?

Re: structured binding vs. iterator pair

Verfasst: 23.05.2018, 23:13
von dot
DerAlbi hat geschrieben:Naja der Defekt ist mMn das man in structured bindings nicht dereferenzieren kann, sodass man - gerade bei trivialen oder mathematischen Typen - direkt mit den Werten arbeiten.
Ich sehe da ein paar Probleme mit dieser Idee dass man in einem Structured Binding dereferenzieren können sollte. Erstens, wo sollte die Dereferenzierung hin? IMHO hat sowas in einem Structured Binding rein prinzipiell keinen logischen Platz, denn wir reden hier eigentlich von der Anwendung eines unären Operators in einer Initializer Expression. Der * neben dem Namen würde im Kontext der restlichen Syntax von C++ eher einer Pointerdeklaration entsprechen als einer Dereferenzierung und wäre für mich z.B. äußerst unintuitiv. Zweitens kann man das gewünschte Verhalten wie oben demonstriert auch erreichen ohne extra nur dafür neue Syntax einzuführen. Die Syntax von C++ ist schon kompliziert genug, für die Einführung neuer Syntax muss es in der Regel eine extrem starke Motivation geben und Konsistenz mit dem Rest der Sprache ist dabei definitiv Grundvoraussetzung. Abgesehen davon: Dereferenzierung ist nur einer von vielen Operatoren. Wieso genau eine Spezialsyntax nur für diesen einen Fall einführen? Was ist mit anderen Operatoren? Negation? Inkrement/Dekrement? Subscript? Call Operator? Du kannst ja ein Proposal schreiben... ;)
DerAlbi hat geschrieben:Ich finde es aber etwas kompliziert, wie du das machst ;-) Wenn man den Typ schon als pair benennt kann man ihn auch direkt nutzen https://godbolt.org/g/WD3CBo
Ich hatte meinen Code erst für std::tuple geschrieben und erst dann gesehen, dass es ja eigentlich ein std::pair braucht. Mein Code lässt sich dafür halt mit allem verwenden wofür std::apply() funktioniert...aber ja, deine Lösung funktioniert auch... ;)
DerAlbi hat geschrieben:kannst du mir sagen, warum du in deinem Beispiel bei begin(..) und end(..) kein std:: davor schreiben musst?
https://en.wikipedia.org/wiki/Argument- ... ame_lookup

Re: structured binding vs. iterator pair

Verfasst: 23.05.2018, 23:39
von DerAlbi
Ich kann da nirgends widersprechen, aber deine Lösung mit der Dereferenzierung des pairs z.B. könnte im pair direkt implementiert sein, wenn beide Typen Pointer (bzw "dereferenzierbar") sind.. die Operation kann man für alles andere ja rausSFINAEn.
Ich weiß auch selbst nicht ob ich nun über die fehlende Option der Dereferenzierung im binding selbst mosere oder viel mehr über die Inkompatibilität, dass man ein überhaupt ein pair aus iteratoren zurückgeben muss. (ich sehe da im Moment den Mehrwert gegenüber Referenzen nicht)

Re: structured binding vs. iterator pair

Verfasst: 23.05.2018, 23:50
von dot
DerAlbi hat geschrieben:Ich kann da nirgends widersprechen, aber deine Lösung mit der Dereferenzierung des pairs z.B. könnte im pair direkt implementiert sein, wenn beide Typen Pointer (bzw "dereferenzierbar") sind.. die Operation kann man für alles andere ja rausSFINAEn.
Könnte ja, welche anderen Operationen sollte man im std::pair dann noch implementieren? Und warum genau die und nicht auch andere? Es steht jedem frei ein Proposal zu schreiben... ;)
DerAlbi hat geschrieben:Ich weiß auch selbst nicht ob ich nun über die fehlende Option der Dereferenzierung im binding selbst mosere oder viel mehr über die Inkompatibilität, dass man ein überhaupt ein pair aus iteratoren zurückgeben muss. (ich sehe da im Moment den Mehrwert gegenüber Referenzen nicht)
Angenommen ich würde gern das größte und kleinste Element aus meinem Container entfernen. Wie mach ich das wenn der Algorithm mir nur eine Referenz auf den Wert des Elements gibt? Der Algorithm sucht mir Elemente in einer Range. Zu einem Element gehört auch die Information über seine Position, nicht nur seinen Inhalt...

Re: structured binding vs. iterator pair

Verfasst: 24.05.2018, 08:57
von DerAlbi
Ich hatte auch an ähnliche Gegenargumente zu Referenzen gedacht, aber auf simples löschen bin ich nicht gekommen :-D
Ich hatte was im Kopf wie "der Abstand zwischen min und max" per std::distance oder so, aber da man die reihenfolge nicht fesstellen kann, klappt das generalisiert z.B. für std::list nicht.
Aber gut, ich denke das Thema ist erledigt. War von vornherein eher esoterisches Ästhetikgedöns ^_^

Re: structured binding vs. iterator pair

Verfasst: 24.05.2018, 15:53
von xq
esoterisches Ästhetikgedöns
Heißt ja nicht, dass es nicht diskutiertenswert wäre... Habe wieder was über C++ gelernt!

Re: structured binding vs. iterator pair

Verfasst: 10.06.2018, 10:23
von Jonathan
Vermutlich wäre dann das, was du eigentlich haben möchtest, eine Funktion std::minmax_value, die dementsprechend Werte statt Iteratoren zurück liefert. Und dann ist es vielleicht eleganter eine solche Funktion zu implementieren, als einen Dereferenzierungsoperator für Tupels.

Re: structured binding vs. iterator pair

Verfasst: 10.06.2018, 23:14
von dot
Jonathan hat geschrieben:Vermutlich wäre dann das, was du eigentlich haben möchtest, eine Funktion std::minmax_value, die dementsprechend Werte statt Iteratoren zurück liefert. Und dann ist es vielleicht eleganter eine solche Funktion zu implementieren, als einen Dereferenzierungsoperator für Tupels.
+1