webentwicklung-frage-antwort-db.com.de

Was sind Use Cases für strukturierte Bindungen?

Der C++ 17-Standard führt eine neue strukturierte Bindung - Funktion ein, die ursprünglich im Jahr 2015 vorgeschlagen wurde und deren syntaktisches Erscheinungsbild weitgehend diskutiert später wurde.

Einige Verwendungszwecke fallen Ihnen ein, sobald Sie die Dokumentation durchgesehen haben.

Aggregatzerlegung

Lassen Sie uns einen Tupel deklarieren:

std::Tuple<int, std::string> t(42, "foo");

Benannte elementweise Kopien können leicht mit strukturierten Bindungen in einer Zeile erhalten werden:

auto [i, s] = t;

was äquivalent ist zu:

auto i = std::get<0>(t);
auto s = std::get<1>(t);

oder

int i;
std::string s;
std::tie(i, s) = t;

Verweise auf Tuple-Elemente können auch schmerzlos erhalten werden:

auto& [ir, sr] = t;
const auto& [icr, scr] = t;

Wir können also Arrays oder Strukturen/Klassen verwenden, deren Mitglieder alle öffentlich sind.

Mehrere Rückgabewerte

Eine bequeme Möglichkeit, mehrere Rückgabewerte von einer Funktion abzurufen, folgt unmittelbar aus dem obigen.

Was noch?

Können Sie andere, möglicherweise weniger offensichtliche Anwendungsfälle für strukturierte Bindungen angeben? Wie können sie die Lesbarkeit oder sogar die Leistung von C++ - Code verbessern?

Notizen

Wie bereits in den Kommentaren erwähnt, weist die derzeitige Implementierung von strukturierten Bindungen einige Mängel auf. Sie sind nicht variabel und ihre Syntax erlaubt es nicht, Aggregatmitglieder explizit zu überspringen. Hier kann man eine Diskussion über Variadizität finden.

15
Sergey

Können Sie andere, möglicherweise weniger offensichtliche Anwendungsfälle für strukturierte Bindungen angeben? Wie können sie die Lesbarkeit oder sogar die Leistung von C++ - Code verbessern?

Im Allgemeinen können Sie es verwenden, um (lassen Sie mich sagen) entpacken eine Struktur und füllen eine Menge von Variablen aus:

struct S { int x = 0; int y = 1; };

int main() {
    S s{};
    auto [ x, y ] = s;
    (void)x, void(y);
}

Der andere Weg wäre gewesen:

struct S { int x = 0; int y = 1; };

int main() {
    S s{};
    auto x = s.x;
    auto y = s.y;
    (void)x, void(y);
}

Dasselbe ist bei Arrays möglich:

int main() {
    const int a[2] = { 0, 1 };
    auto [ x, y ] = a;
    (void)x, void(y);
}

Wie dem auch sei, denn es funktioniert auch, wenn Sie die Struktur oder das Array von einer Funktion zurückgeben. Wahrscheinlich können Sie argumentieren, dass diese Beispiele zu den gleichen Fällen gehören, die Sie bereits erwähnt haben.


Ein weiteres gutes Beispiel, das in den Kommentaren zur Antwort von @TobiasRibizel erwähnt wurde, ist die Möglichkeit, Container zu durchlaufen und den Inhalt leicht zu entpacken.
Als Beispiel basierend auf std::map:

#include <map>
#include <iostream>

int main() {
    std::map<int, int> m = {{ 0, 1 }, { 2, 3 }};
    for(auto &[key, value]: m) {
        std::cout << key << ": " << value << std::endl;
    }
}
12
skypjack

Können Sie andere, möglicherweise weniger offensichtliche Anwendungsfälle für strukturierte Bindungen angeben? 

Sie können verwendet werden, um get<N> für Strukturen zu implementieren - siehe magic_getS AUTOMATISCH GENERIERTE core17_generated.hpp . Dies ist nützlich, da es eine primitive Form der statischen Reflexion bereitstellt (z. B. alle Mitglieder eines structdurchlaufen) .

9
Vittorio Romeo

Ohne gegenteilige Beweise denke ich, dass strukturierte Bindungen nur ein Mittel sind, um mit älteren APIs umzugehen. IMHO, die APIs, die SB erfordern, sollten stattdessen behoben worden sein.

Also statt

auto p = map.equal_range(k);
for (auto it = p.first; it != p.second; ++it)
    doSomethingWith(it->first, it->second);

wir sollten schreiben können

for (auto &e : map.equal_range(k))
    doSomethingWith(e.key, e.value);

Anstatt

auto r = map.insert({k, v});
if (!r.second)
    *r.first = v;

wir sollten schreiben können

auto r = map.insert({k, v});
if (!r)
    r = v;

usw.

Sicher, jemand wird irgendwann eine kluge Verwendung finden, aber für mich sind sie nach einem Jahr, in dem ich sie kennen gelernt habe, immer noch ein ungelöstes Rätsel. Esp. da das Papier von Bjarne gemeinsam verfasst wurde, ist er normalerweise nicht dafür bekannt, Funktionen einzuführen, die eine so enge Anwendbarkeit haben.

1