2016-01-28 2 views
15

Je voudrais parcourir une valarray temporaire, mais cela ne fonctionne pas. Voici ma (non-travail) Code:La plage C++ pour la boucle sur valarray rvalue ne fonctionne pas

#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; 
} 

est Ci-dessous un exemple de travail minimum de ce que je voudrais réaliser, sauf que je ne veux pas définir un objet comme temp_array.

#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; 
} 

Mon compilateur est g ++ version 4.8.5 (Red Hat 4.8.5-4). Je compile avec le drapeau -std = C++ 0x.

J'ai essayé d'autres syntaxes telles que for (auto&& i : temp_array) et for (int const & i : temp_array), mais cela ne fonctionne pas.

+2

opérateur '' de valarray'/'est autorisé à renvoyer un proxy objet un des modèles d'expression La. – chris

+0

J'ai été loin de C++ pendant trop longtemps, apparemment. Quelqu'un pourrait-il expliquer comment 'for (int i: temp_array) {}' est une instruction de boucle valide? Ne devrait-il pas être quelque chose comme 'for (init; end_condition; increment)'? – user1717828

+0

@ user1717828 Voir la boucle de C++ 11 basée sur la gamme. – milleniumbug

Répondre

11

Comme indiqué dans @Yam Marcovivc's answer le résultat de l'opération n'est pas garanti d'être un std::valarray<int> qui peut être transmis directement à std::begin(). Un objet construit temporaire fait l'affaire:

#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; 
} 

Voir un Live Demo

18

De la documentation (qui comprend également la façon officielle de le faire en une seule expression):

Contrairement à d'autres fonctions qui prennent std :: arguments valarray, begin() ne peut pas accepter les types de remplacement (par exemple, std :: begin (v1 + v2) n'est pas portable, std :: begin (std :: valarray (v1 + v2)) doit être utilisé comme les types produits par les templates d'expression) qui peuvent être retournés à partir d'expressions impliquant valarrays: au lieu.

Cette fonction a pour but de permettre aux boucles de fonctionner avec valarrays, et non de fournir une sémantique de conteneur.

Quant à ce qui pourrait être la raison pour laquelle, il y a aussi ce (qui a été signalée par @ Chris):

[opérateurs arithmétiques] peuvent être mises en œuvre avec le type de retour différent de std :: valarray .

Donc, techniquement, rien ne garantit que les retours peuvent être transmis en toute sécurité à std::begin.

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

Fonctionne, mais recommander des moulages de type C n'est peut-être pas le meilleur conseil. De plus, le simple fait d'afficher du code sans autre explication (et faisant référence à d'autres réponses) ne constitue pas une excellente réponse. –