Problem mit pair und vector
-
Ich hab ein Paar Breakpoints gesetzt und mir auch mal die size() ausgeben lassen.
-
Kleine Kritik:
for (unsigned long i = computed_orders.size(); i < order; ++i) { computed_orders.push_back(0); map_order_to_index.push_back(-1); }
computed_orders .resize( order, 0 ); map_order_to_index.resize( order, std::numeric_limits<unsigned int>::max() ); // Edit: Ist die zweite Zeile auch korrekt? Ist die Größe von map_order... dieselbe wie die von computed_orders?_________________________________________________________________________
nodes.push_back(new_nodesAndWeights.first); weights.push_back(new_nodesAndWeights.second);Falls möglich umschreiben zu
nodes .push_back( std::move(new_nodesAndWeights.first ) ); weights.push_back( std::move(new_nodesAndWeights.second) );_________________________________________________________________________
pair<vector<double>*, vector<double>* > nodesAndWeights_forOrder; nodesAndWeights_forOrder.first = &nodes[order]; nodesAndWeights_forOrder.second = &weights[order]; return nodesAndWeights_forOrder;
return {&nodes[order], &weights[order]};
-
Danke Arcoth, das ist natürlich eleganter! Übernehme ich sofort!
Nachdem ich den Post abgeschickt habe hat's keine 5 Minuten mehr gedauert:
Ich Idiot hab' falsch auf die Daten zugegriffen. Richtig ist:
nodesAndWeights_forOrder.first = &nodes[map_order_to_index[order]]; nodesAndWeights_forOrder.second = &weights[map_order_to_index[order]];Witzig, dass sich der Compiler nicht beschwert hat (-Wall -pedantic), und trotzdem an erster Stelle das richtige Ergebnis stand.
Sorry Dafür!
-
Wäre es nicht zweckmäßig, Knoten und Gewichte zusammen zu speichern?
vector< vector< pair< double, double > > > weighted_nodes; // oder wenigstens vector< pair< vector< double >, vector< double > > > weighted_nodes;Der gesamte if-Zweig sollte in einer eigenen Funktion stehen. Dann wird das Ganze übersichtlicher.
nodes .push_back( std::move(new_nodesAndWeights.first ) ); weights.push_back( std::move(new_nodesAndWeights.second) );andere Variante wäre hier mal tie zu verwenden:
nodes.push_back( {} ); weights.push_back( {} ); tie( nodes.back(), weights.back() ) = compute_nodesAndWeights_gaussLobattoQuadrature(order);(mit weighted_nodes wird es noch einfacher).
EIn Rückgabetyp
pair<vector<double>&, vector<double>& >könnte syntaktisch bequemer sein. Dann ist nämlich zum Beispiel der Zugriff etwa auf den Indexoperator der Vectoren direkt möglich, sonst erfordert die extra Derenzierung zusätzlichen Schreibaufwand.
-
Hi Camper,
das mit dem Rückgabetyp ist ein guter Einwand!tie hab' ich bisher noch nie wirklich genutzt, die Doku dazu sieht aber vielversprechend aus für das, was ich eigentlich suche.
Mein erster Versuch für die Klasse war mit deinem zweiten Vorschlag:
vector< pair< vector< double >, vector< double > > > weightsAndNodes;Da hab' ich aber eben mit den Rückgabetypen was nicht hin bekommen:
Angenommen ich nehme das Format oben.
Was ist denn dann mein Rückgabetyp??
Das hier:pair < vector < double > , vector < double > >&?
Sorry, aber bei sowas bin ich immer total hilflos..Danke für eure Hilfe!
-
denis2102 schrieb:
Angenommen ich nehme das Format oben.
Was ist denn dann mein Rückgabetyp??
Das hier:pair < vector < double > , vector < double > >&Genau (pair < vector < double >&, vector < double >& >) würde allerdings auch funktionieren.
Die Berechnung wird dann einfach zu
weightsAndNodes.emplace_back( compute_nodesAndWeights_gaussLobattoQuadrature(order));
-
Danke für deine Tipps!
Ich habe das mit den Rückgabetypen nicht so richtig hinbekommen, und werde die Infos jetzt einfach als 2 2d-Vektoren speichern. So eine große Rolle spielt das ja nicht.Die Rückgabefunktion sieht jetzt so aus, und funktioniert:
pair < vector<double>&, vector<double>& > Computation_Safe::get_nodesAndWeights_forOrder(unsigned int order) { resize_ifNecessary(order); // Berechnet auch Gewichte und Knoten falls nötig return { nodes[map_order_to_index[order]],weights[map_order_to_index[order]] }; }1. Frage: Der Tipp mit den geschweiften Klammern kam von euch aus dem Forum. Was genau macht das?
2. Frage: Kann mir jemand erklären wie ich denn jetzt den Rückgabetyp mit make_pair (theoretisch) angeben könnte??
return make_pair(nodes[map_order_to_index[order]],weights[map_order_to_index[order]]bringt mir nur ein 'no viable conversion from [...] to [...]'.
EDIT: Wenn ich die Arbeit abgebe, muss ich das auf jeden Fall noch umschreiben. Die Version mit den geschweiften Klammern kompiliert problemlos in xCode, aber nur unter Verwendung vom LLVM Compiler. Sowohl G++ als auch CLANG bekommen das (aus dem Terminal) nicht kompiliert.
Liebe Grüße,
Denis
-
denis2102 schrieb:
bringt mir nur ein 'no viable conversion from [...] to [...]'.
was genau in den [...] steht, würde uns da schon interessieren.
denis2102 schrieb:
Die Version mit den geschweiften Klammern kompiliert problemlos in xCode, aber nur unter Verwendung vom LLVM Compiler. Sowohl G++ als auch CLANG bekommen das (aus dem Terminal) nicht kompiliert.
-std=c++0x oder -std=c++11 mit angeben
-
Die komplette Fehlermeldung ist
No viable conversion from 'pair<typename __make_pair_return<class vector<double, class allocator<double> > &>::type, typename __make_pair_return<class vector<double, class allocator<double> > &>::type>' to 'pair<vector<double> &, vector<double> &>'Das mit -std=C++** funktioniert dabei auch nicht.
Was macht denn jetzt die geschweifte Klammer?
Verzeiht meine Ratlosigkeit

-
stimmt, müsste
return make_pair(std::ref(nodes[map_order_to_index[order]]),std::ref(weights[map_order_to_index[order]]));lauten und braucht dann auch C++11. In C++03 bleibt dir nichts anderes übrig, als den Rückgabetypen direkt beim return nochmal hinzuschreiben.
-
nodes.push_back( {} ); weights.push_back( {} );Hier sollte wohl eher
emplace_backohne Argumente stehen.weightsAndNodes.emplace_back( compute_nodesAndWeights_gaussLobattoQuadrature(order));Und hier sollte
push_backstehen.Noch kürzer geht es auch
tie( *back_inserter(nodes), *back_inserter(weights) ) = compute_nodesAndWeights_gaussLobattoQuadrature(order);Was genau macht das?
Das nennt sich list-initialization; hier speziell copy-list-initialization. Es übergibt - grob beschrieben - die Listenelemente als Konstruktorargumente an das Rückgabeobjekt.
-
Arcoth schrieb:
tie( *back_inserter(nodes), *back_inserter(weights) ) = compute_nodesAndWeights_gaussLobattoQuadrature(order);interessante Idee.