std :: mit strukturierten Bindungen ignorieren?

82

Auftakt:

std::tuple<int, int, int> f();
std::tuple<int, int, float, int> g();

C ++ 1z führt eine Syntax für strukturierte Bindungen ein, die das Schreiben anstelle von ermöglicht

int a, b, c;
std::tie(a, b, c) = f();

etwas wie

auto [a, b, c] = f();

Es std::tiedarf jedoch auch angegeben werden std::ignore, bestimmte Komponenten zu ignorieren, z.

std::tie(a, b, std::ignore, c) = g();

Wird es möglich sein, mit der neuen Syntax für strukturierte Bindungen etwas Ähnliches zu tun? Wie würde es funktionieren?

jotik
quelle
2
Geben Sie dort einfach einen beliebigen Namen ein.
n. 'Pronomen' m.
1
@nm erstellt kein beliebiger Name eine Kopie?
Piotr Skotnicki
1
@Piotr Nicht mehr Kopien als mit std::ignore, denke ich. Da wir die Kopierelision garantiert haben, wird die Dummy-Variable initialisiert. mit std::tiewird das temporäre Element std::ignoreinitialisiert , das sich am Anfang der Zuweisung befindet.
6.
1
Es wäre möglich, ein Makro zu haben auto[IGNORE], das einen eindeutigen Namen generiert (z. B. mit compilerspezifischem COUNTER oder LINE ). Es wäre lesbar genug und würde in der Praxis wie std::ignorefür funktionieren std::tie.
KABoissonneault
2
@PiotrSkotnicki Nein, die einzige Kopie, die eine Dekompensationsdeklaration erstellt, ist die Sache, die zerlegt wird. Die deklarierten Dinge sind entweder Aliase für die Mitglieder / Elemente dieser Sache oder Verweise, die an das gebunden sind, was getzurückgibt.
TC

Antworten:

57

Der Vorschlag für strukturierte Bindungen enthält einen eigenen Abschnitt zur Beantwortung Ihrer Frage ( P0144R2 ):

3.8 Sollte es eine Möglichkeit geben, Komponenten explizit zu ignorieren?

Die Motivation wäre, Compiler-Warnungen vor nicht verwendeten Namen zum Schweigen zu bringen. Wir denken, die Antwort sollte "noch nicht" sein. Dies ist nicht durch Anwendungsfälle motiviert (das Stummschalten von Compiler-Warnungen ist eine Motivation, aber kein Anwendungsfall an sich) und wird am besten so lange belassen, bis wir dies im Rahmen eines allgemeineren Vorschlags für den Mustervergleich erneut prüfen können, bei dem dies herausfallen sollte als Sonderfall.

Symmetrie mit std::tiewürde vorschlagen, etwas zu verwenden wie std::ignore:

tuple<T1,T2,T3> f();

auto [x, std::ignore, z] = f(); // NOT proposed: ignore second element

Dies fühlt sich jedoch unangenehm an.

Das Vorwegnehmen des Mustervergleichs in der Sprache könnte auf einen Platzhalter wie _oder hindeuten. *Da wir jedoch noch keinen Mustervergleich haben, ist es verfrüht, eine Syntax auszuwählen, von der wir wissen, dass sie kompatibel ist. Dies ist eine reine Erweiterung, die darauf warten kann, bei der Mustererkennung berücksichtigt zu werden.

Beachten Sie jedoch, dass der Arbeitsentwurf des Standards derzeit von den zuständigen nationalen Stellen (NB) überarbeitet wird und ein NB-Kommentar diese Funktion anfordert ( P0488R0 , US100):

Dekompositionsdeklarationen sollten eine Syntax bereitstellen, um einige der zurückgegebenen Werte ebenso wie std::tieVerwendungen zu verwerfen std::ignore.

Metallfuchs
quelle
6
Es ist jetzt zu spät, aber ich möchte darauf hinweisen, dass eine Funktion, deren Verwendung sich unangenehm anfühlt und die wahrscheinlich in Zukunft ersetzt wird, besser ist, als überhaupt nicht in der Lage zu sein, die Funktion zu verwenden , und dies scheint nicht die Art von zu sein was das Normungskomitee dazu bringt, sich eine Zeitmaschine zu wünschen, weil es keine andere vernünftige Interpretation std::ignorein strukturierten Bindungen gibt.
Daniel H
9

Wird es möglich sein, mit der neuen Syntax für strukturierte Bindungen etwas Ähnliches zu tun?

Nein. Sie müssen nur einen Variablennamen erstellen, der später nicht erwähnt wird.

Nicol Bolas
quelle
25
-Wunused-variableSie können eine nicht verwendete Variablenwarnung generieren , die Sie verwenden können. Dies [[maybe_unused]] auto [ a, b, dummy ] = std::tuple(1,"2",3f);bedeutet jedoch, dass eine von ihnen möglicherweise nicht verwendet wird. Sie wissen nicht, welche. Für diesen Fall gibt es derzeit keine gute Lösung. hoffentlich wird es in c ++ 20 verbessert. von hier genommen: stackoverflow.com/questions/41404001/…
serine
3
"Für diesen Fall gibt es derzeit (void)dummy;keine gute Lösung" : Das stimmt nicht ganz: Sie können einfach die Warnung für nicht verwendete Variablen entfernen, ohne die anderen Variablen zu beeinflussen.
andreee
16
@andreee: Eine Anweisung nur zu verwenden, um eine Warnung zu beruhigen, würde ich nicht als "gute Lösung" bezeichnen.
Nicol Bolas
"Eine Anweisung verbrauchen, nur um eine Warnung zu beruhigen ..." Gehen uns die Anweisungen aus?
AndyJost
1
@AndyJost: Nein, aber wir haben nicht mehr genügend visuellen Platz auf dem Bildschirm. Es ist nicht sinnvoll, einen besonders wertvollen vertikalen Raum für die Beruhigung einer Warnung aufzuwenden.
Nicol Bolas