2016-11-11 10 views
1

У меня есть простое использование обхода временного std::valarray выражения в диапазоне для цикла, но получило error: выражение недопустимого диапазона ...Недопустимого выражения диапазона станд :: valarray в диапазоне для цикла

main.cpp

#include <iostream> 
#include <valarray> 

int main() 
{ 

    std::valarray<int> xxx {2,7,1,8,2,8}; 
    std::valarray<int> zzz {xxx}; 

    for (auto x : xxx + zzz) std::cout << x << std::endl; 

    return 0; 
} 

лязг ++ main.cpp -std = C++ 11

main.cpp:10:17: error: invalid range expression of type 'std::__1::__val_expr<std::__1::_BinaryOp<std::__1::plus<int>, std::__1::valarray<int>, std::__1::valarray<int> > >'; no viable 'begin' function available 
    for (auto x : xxx + zzz) std::cout << x << std::endl; 
       ^~~~ 

Я Неужели это действительно хорошая причина, что он не компилируется, как я ожидал? Тип возврата перегруженного operator+ равен valarray<T>, поэтому теоретически значение выражения должно быть временным экземпляром типа valarray<T>.

Синопсис:

template<class T> valarray<T> operator+ (const valarray<T>& x, const valarray<T>& y); 

Версия: компании Apple LLVM версии 8.0.0 (лязг-800.0.38) Цель: x86_64-яблочно-darwin15.6.0

Примечание следующая строка работы

for (auto x : xxx += zzz) std::cout << x << std::end; 
+1

Да, поскольку 'valarray' использует шаблоны выражений. –

+1

VS2013 компилирует его без ошибок. – acraig5075

+0

@ acraig5075 Хорошая точка. Я также просто проверил на http://rextester.com/l/cpp_online_compiler_visual –

ответ

0

Что вы хотите сделать? Если вы хотите пройти ххх сделать для только в нем:

for (const auto x : xxx) std::cout << x << std::endl; 

Но отвечая на основы вашего вопроса, то выражение (ххх + ууу) не итерацию. Если вы хотите, чтобы сделать цикл в обоих, вы делаете два Fors:

for (auto x : xxx) std::cout << x << std::endl; 
for (auto x : zzz) std::cout << x << std::endl; 

Если вы хотите сделать это в одном цикле, вы можете добавить как

xxx += yyy; 
for (auto x : xxx) std::cout << x << std::endl; 

PD от Edit: line

for (auto x : xxx += yyy) std::cout << x << std::endl; 

работает, потому что он делает присоединение первым, а затем выполняет итерации. Это эквивалентно моему последнему предложению. Но (xxx + yyy) не повторяется.

От ваших комментариев: valrray :: operator + (valarray) не существует. valrray :: operator + = (valarray) действительно существует.

+0

«выражение (xxx + yyy) не является произносимым» - почему? –

+0

@LanceLi конечно нет. – LeDYoM

+0

@LanceLi результат xxx + yyy - это то, что не является итерируемым. Оператор + отличается от оператора + =. – LeDYoM

1

Как «начало» и «конец» доступны для возвращаемого типа operator+, а именно: valarray<T> Я бы сказал, что ошибка неверна и она должна скомпилироваться.

+1

По каким-либо причинам gcc и и clang возвращают 'std :: _ Expr , int>' вместо 'std :: valarray '. –

+0

Вот почему я прошу ... vC++ может это сделать. –

+0

Возвратный тип оператора + для valarrays не требуется для std :: valarray (и я бы даже сказал, что это std :: valarray, реализация нарушена) – Cubbi

0

Диапазон для цикла использует не-член std :: begin и std :: end, которые не требуются для существования типа возврата оператора + для std :: valarray.

Переносной синтаксис

for(auto x : std::valarray<int>(xxx + zzz)) 

Это отмечено на cppreference и в стандарте под 26.7.1 [valarray.syn] p4.1