2016-01-28 18 views
15

Ich möchte über ein temporäres valarray iterieren, aber es funktioniert nicht. Hier ist mein (ohne Funktion) Code:C++ range-based für Schleife über Valarray rvalue funktioniert nicht

#include <iostream> 
#include <valarray> 
int main() 
{ 
     using namespace std; 
     valarray<int> numerators = {99, 26, 25}; 
     valarray<int> denominators = {9, 2, 5}; 
     for (int i : numerators/denominators) { cout << i << ","; } 
     // lots of errors 
     return 0; 
} 

Nachfolgend finden Sie ein minimales Arbeits Beispiel dafür, was Ich mag würde erreichen, mit der Ausnahme, dass ich nicht ein Objekt wie temp_array definieren will.

#include <iostream> 
#include <valarray> 
int main() 
{ 
     using namespace std; 
     valarray<int> numerators = {99, 26, 25}; 
     valarray<int> denominators = {9, 2, 5}; 
     valarray<int> && temp_array = numerators/denominators; 
     for (int i : temp_array) { cout << i << ","; } 
     // prints 11,13,5, 
     return 0; 
} 

Mein Compiler ist G ++ Version 4.8.5 (Red Hat 4.8.5-4). Ich kompiliere mit dem Flag -std = C++ 0x.

Ich habe andere Syntax wie for (auto&& i : temp_array) und for (int const & i : temp_array) versucht, aber es funktioniert nicht.

+2

'valarray' der' Operator/'darf ein Proxy-Objekt ein la Ausdruck Vorlagen zurückzukehren. – chris

+0

Ich war anscheinend zu lange weg von C++. Könnte jemand erklären, wie 'for (int i: temp_array) {}' eine gültige for-Schleife-Anweisung ist? Sollte es nicht etwas wie 'for (init; end_condition; increment)' sein? – user1717828

+0

@ user1717828 Siehe C++ 11 die bereichsbasierte for-Schleife. – milleniumbug

Antwort

11

Wie wies darauf hin, in @Yam Marcovivc's answer das Operationsergebnis nicht ein std::valarray<int> sein wird garantiert, die direkt an std::begin() weitergegeben werden können. Eine temporäre konstruiertes Objekt funktioniert der Trick:

#include <iostream> 
#include <valarray> 
int main() 
{ 
     using namespace std; 
     valarray<int> numerators = {99, 26, 25}; 
     valarray<int> denominators = {9, 2, 5}; 
     for (int i : valarray<int>(numerators/denominators)) { 
      cout << i << ","; 
     } 
     return 0; 
} 

Siehe ein Live Demo

18

Aus der Dokumentation (die auch die offizielle Art und Weise enthält diese in einem einzigen Ausdruck zu tun):

Im Gegensatz zu anderen Funktionen, die std :: valarray Argumente nehmen, beginnen() kann die Ersatztypen nicht akzeptieren (z wie die Typen, die von Ausdruckschablonen erzeugt werden), die von Ausdrücken zurückgegeben werden können, die valarrays enthalten: std :: begin (v1 + v2) ist nicht portierbar, std :: begin (std :: valarray (v1 + v2)) muss verwendet werden stattdessen.

Die Absicht dieser Funktion ist es zu ermöglichen, dass Bereich für Schleifen mit Valarrays arbeiten, nicht Container Semantik.

Betreffs, was könnte der Grund sein, es gibt auch diese (die von @ Chris darauf hingewiesen wurde):

[arithmetische Operatoren] kann mit dem Rückgabetyp implementiert werden, die sich von std :: valarray .

Es gibt also technisch nichts zu garantieren, dass die Rücksendung sicher an std::begin weitergegeben werden kann.

3
for (int i : (valarray<int> &&)(numerators/denominators)) { cout << i << ","; } 
+9

Works, aber C-Style-Casts empfehlen möglicherweise nicht der beste Rat sein. Auch das Posten von Code ohne weitere Erklärungen (und es bezieht sich auf andere Antworten) macht dies keine gute Antwort. –