2016-01-28 13 views
15

Я хотел бы перебирать временный valarray, но он не работает. Вот мой (нерабочий) Код:C++ диапазон для цикла по valarray rvalue не работает

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

Ниже приведен минимальный рабочий пример того, что я хотел бы достичь, за исключением того, что я не хочу, чтобы определить объект как 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; 
} 

Мой компилятор - g ++ версия 4.8.5 (Red Hat 4.8.5-4). Я компилирую с флагом -std = C++ 0x.

Я пробовал другой синтаксис, такой как for (auto&& i : temp_array) и for (int const & i : temp_array), но он не работает.

+2

'' оператор valarray' в/'разрешено возвращать прокси-объект а-ля шаблонов выражений. – chris

+0

Я слишком долго отсутствовал от C++. Может ли кто-нибудь объяснить, как 'for (int i: temp_array) {}' является действительным для оператора цикла? Не должно быть что-то вроде 'for (init; end_condition; increment)'? – user1717828

+0

@ user1717828 См. Раздел C++ 11 для цикла. – milleniumbug

ответ

11

Как указано в @Yam Marcovivc's answer результат операции не гарантируется быть std::valarray<int>, которые могут быть переданы непосредственно в std::begin(). Временный построенный объект делает трюк:

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

увидеть Live Demo

18

Из документации (которая также включает в себя официальный способ сделать это в одном выражении):

В отличие от других функций, которые принимают аргументы станд :: valarray, начать() не может принимать типы замены (например как типы, создаваемые шаблонами выражений), которые могут быть возвращены из выражений с участием valarrays: std :: begin (v1 + v2) не переносится, std :: begin (std :: valarray (v1 + v2)) должен использоваться вместо.

Цель этой функции - разрешить диапазон для циклов работать с valarrays, а не предоставлять семантику контейнера.

Относительно того, что может быть причиной, есть также это (который указывал @ Крис):

[арифметические операторы] могут быть реализованы с типом возвращаемого значения, отличного от станд :: valarray ,

Таким образом, нет ничего, что могло бы гарантировать,

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

Работы, но рекомендующие c-style casts, возможно, не лучший совет. Также просто отправить код без каких-либо дальнейших объяснений (и, если ссылаться на другие ответы) не делает это отличным ответом. –

 Смежные вопросы

  • Нет связанных вопросов^_^