Диапазон С++ для цикла по valarray rvalue не работает
Я хотел бы перебирать временную valarray, но она не работает. Вот мой (нерабочий) код:
#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 = С++ 0x.
Я пробовал использовать другой синтаксис, например for (auto&& i : temp_array)
и for (int const & i : temp_array)
, но он не работает.
Ответы
Ответ 1
Как указано в ответе @Yam Marcovivc, результат операции не гарантируется как 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
Ответ 2
Из документации (которая также включает официальный способ сделать это в одном выражении):
В отличие от других функций, которые принимают аргументы std:: valarray, begin() не может принимать типы замещения (например, типы, созданные шаблонами выражений), которые могут быть возвращены из выражений с использованием valarrays: std:: begin (v1 + v2) не переносится, вместо этого следует использовать std:: begin (std:: valarray (v1 + v2)).
Цель этой функции - разрешить диапазон для циклов работать с valarrays, а не предоставлять семантику контейнера.
В зависимости от того, что может быть причиной, есть и это (на что указывает @chris):
[арифметические операторы] могут быть реализованы с использованием типа возврата, отличного от std:: valarray.
Таким образом, технически нечего гарантировать, что возврат может быть безопасно передан на std::begin
.
Ответ 3
for (int i : (valarray<int> &&)(numerators / denominators)) { cout << i << ","; }