structured binding vs. iterator pair

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.

structured binding vs. iterator pair

Beitragvon DerAlbi » 23.05.2018, 05:31

Hallo Leute,
ich habe folgenden Code:
Code: Ansicht erweitern :: 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: Ansicht erweitern :: 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: Ansicht erweitern :: 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: Ansicht erweitern :: 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
DerAlbi
Establishment
 
Beiträge: 229
Registriert: 20.05.2011, 05:37

Re: structured binding vs. iterator pair

Beitragvon dot » 23.05.2018, 18:54

Woran genau scheitert es? https://godbolt.org/g/beYjDg
Benutzeravatar
dot
Michael Kenzel
Establishment
 
Beiträge: 1647
Registriert: 06.03.2004, 19:10

Re: structured binding vs. iterator pair

Beitragvon DerAlbi » 23.05.2018, 19:35

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.
DerAlbi
Establishment
 
Beiträge: 229
Registriert: 20.05.2011, 05:37

Re: structured binding vs. iterator pair

Beitragvon dot » 23.05.2018, 19:54

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
Benutzeravatar
dot
Michael Kenzel
Establishment
 
Beiträge: 1647
Registriert: 06.03.2004, 19:10

Re: structured binding vs. iterator pair

Beitragvon DerAlbi » 23.05.2018, 21:16

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?
DerAlbi
Establishment
 
Beiträge: 229
Registriert: 20.05.2011, 05:37

Re: structured binding vs. iterator pair

Beitragvon dot » 23.05.2018, 23:13

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
Benutzeravatar
dot
Michael Kenzel
Establishment
 
Beiträge: 1647
Registriert: 06.03.2004, 19:10

Re: structured binding vs. iterator pair

Beitragvon DerAlbi » 23.05.2018, 23:39

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)
DerAlbi
Establishment
 
Beiträge: 229
Registriert: 20.05.2011, 05:37

Re: structured binding vs. iterator pair

Beitragvon dot » 23.05.2018, 23:50

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...
Benutzeravatar
dot
Michael Kenzel
Establishment
 
Beiträge: 1647
Registriert: 06.03.2004, 19:10

Re: structured binding vs. iterator pair

Beitragvon DerAlbi » 24.05.2018, 08:57

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 ^_^
DerAlbi
Establishment
 
Beiträge: 229
Registriert: 20.05.2011, 05:37

Re: structured binding vs. iterator pair

Beitragvon MasterQ32 » 24.05.2018, 15:53

esoterisches Ästhetikgedöns

Heißt ja nicht, dass es nicht diskutiertenswert wäre... Habe wieder was über C++ gelernt!
Wer checkt diese Shaderprogrammierung denn?
JCL: Kein Mensch zwingt Sie jedoch, mit Shadern oder ueberhaupt mit Gamestudio zu arbeiten. Es gibt schliesslich auch andere schoene Hobbies, wie zum Beispiel das Sammeln von Bierdeckeln – JCL quotes
Benutzeravatar
MasterQ32
Felix Queißner
Establishment
 
Beiträge: 1194
Registriert: 07.10.2012, 14:56

Re: structured binding vs. iterator pair

Beitragvon Jonathan » 10.06.2018, 10:23

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.
Lieber dumm fragen, als dumm bleiben!
Benutzeravatar
Jonathan
Establishment
 
Beiträge: 1221
Registriert: 04.08.2004, 20:06

Re: structured binding vs. iterator pair

Beitragvon dot » 10.06.2018, 23:14

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
Benutzeravatar
dot
Michael Kenzel
Establishment
 
Beiträge: 1647
Registriert: 06.03.2004, 19:10


Zurück zu Programmiersprachen, Quelltext und Bibliotheken

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste