std::copy mit Werten aus einer struct
-
Hallo,
ich bin gerade zu blöd dafür:
Wenn ich statt 'passende' vectors kopiere, wie hier:
vector<int> src = { 1, 2, 3 }; vector<int> dest = { 4, 5, 6 }; std::copy(src.begin(), src.end(), std::back_inserter(dest));
wie mache ich das, wenn die zu kopierenden Werte noch gekapselt sind, also so
struct s { int i; }; vector<s> src = { {1}, {2}, {3} }; vector<int> dest = { 4, 5, 6 }; std::copy(src.begin(), src.end(), std::back_inserter(dest)); // ?
Also in schön und nicht über eine for-Schleife?
-
guck dir
std::transform
an.
-
So direkt geht das nicht, da aus sicht von C++
s
undint
gänzlich inkompatible Typen sind. Nun gibt es zwei Ansätze:- Der schnöde technische Ansatz, wenn es dir nur um die richtige Syntax geht. Du brauchst halt etwas, das dir dein
s
in einenint
auspackt und in den Zielvector schreibt. Hier böte sich ein kurzes lambda an:std::for_each(src.begin(), src.end(), [&dest](s val){dest.push_back(val.i);});
.
Warum habe ichfor_each
und nichtcopy
benutzt? Weilcopy
einen ausgewachsenen Outputiterator erwartet, inklusive solcher Dinge wie einem Membervalue_type
. Das kann man nicht mehr in eine kurze Zeile schreiben. - Ansatz über das Datenmodell. Bin ich ein Fan von. Es ist hier zwar ein akademisches Beispiel, aber im echten Leben wäre die Frage doch jetzt, wieso jemand ein
s
in einenint
konvertiert haben möchte, wenn die Modellierung vons
doch ausdrückt, dass es mitint
nichts zu tun hat. Also ist das entweder ein Logikfehler seitens des Programmierers, der hier inkompatible Objekte ineinander überführen will, oder das Datenmodell ist falsch (oder Möglichkeit 3: Das Modell ist richtig und der Programmierer ist sich der Gefahr bei der Umwandlung bewusst, will es aber trotzdem aus Günden. Aber für gefährliche Konvertierungen gibt es ein besseres Sprachmittel, nämlich denreinterpet_cast
). Wenn das Modell vons
falsch ist, als das eine Konvertierung nachint
ausdrücklich erlaubt sein soll, dann sollte man diese auch anbieten (z.B.operator int() const {return i;}
). Dann funktioniert auch dascopy
direkt und ohne Änderung, denn dann ist das ja eine ganz logische und sichere Operation.
- Der schnöde technische Ansatz, wenn es dir nur um die richtige Syntax geht. Du brauchst halt etwas, das dir dein
-
@Bashar
Du meinst erst transformieren und dann copy oder?
Nee,das gefällt mir nicht; da scheint mir eine Schleife besser lesbar.@SeppJ
Gut zu wissen, dass ich da zumindest nichts offensichtliches übersehen habe.Falls es dich interessiert: S ist eine grosse Datenklasse ; S.i und dest sind IDs.
dest (also die IDs) sind ein Parameter und in der Funktion werden die Ss entsprechend behalten, geladen oder gelöscht.Danke für die Ratschläge.
-
@Jockelx Ach Kind
#include <vector> #include <algorithm> #include <iostream> using namespace std; int main() { struct s { int i; }; vector<s> src = { {1}, {2}, {3} }; vector<int> dest = { 4, 5, 6 }; transform(begin(src), end(src), back_inserter(dest), [](auto& v ) { return v.i; } ); for( auto i: dest ) cout << i << " "; cout << "\n"; }
-
@Jockelx sagte in std::copy mit Werten aus einer struct:
@Bashar
...std::transform(src.begin(), src.end(), std::back_inserter(dest), [](auto& s) { return s.i; });
-
@Bashar
Ja, klar, dumme Frage.
-
@Jockelx sagte in std::copy mit Werten aus einer struct:
@Bashar
Du meinst erst transformieren und dann copy oder?
Nee,das gefällt mir nicht; da scheint mir eine Schleife besser lesbar.Nein, er meint so wie ich das gemacht habe mit
for_each
. Die Unterschiede zwischentransform
undfor_each
(und auchmap
) sind ziemlich fein und es geht eher darum, was man inhaltlich damit ausdrücken möchte. Hier wäre nach allem was du sonst so gesagt hast,transform
wahrscheinlich die bessere WahlFalls es dich interessiert: S ist eine grosse Datenklasse ; S.i und dest sind IDs.
Dann passt das Datenmodell, aber deine ursprüngliche Frage hat einen völlig falschen Eindruck erweckt.