I think that the default overload of ==
for valarray
is not very convenient. By default x==y
(for two valarrays x and y) returns a valarray<bool>
, with true
on the i
th entry if x[i]==y[i]
. Rather, I need a single bool
, which tells me if both valarray<double>
contain the same elements or not. I know I can do this with a cycle, but having to do the cycle every time is not convenient. What's the best workaround here? Is there a way for me to define my own overload of ==
(and also !=
, <
, and so on)?

- 18,594
- 33
- 93
- 169
-
3http://stackoverflow.com/questions/24628918/strange-c-compile-error-with-valarrays – Miki Jun 29 '15 at 21:27
-
do a `sum` on the `std::valarray
` – user3528438 Jun 29 '15 at 21:27 -
@user3528438 `sum` would `and` the bools? – a06e Jun 29 '15 at 21:36
-
1Would it be convenient to wrap the return value of `valarray
` with `std::all_of`? – Arun Jun 30 '15 at 00:00
4 Answers
"Not very convenient"? This behaviour is exactly the reason for valarray
.
To override it would be entirely self-defeating.
If you don't like it, just use a vector
instead.

- 378,754
- 76
- 643
- 1,055
-
I like how `x+y` works for `valarray`, and I couldn't do that if I used `vector`. But I think `x==y` should return a single `bool`. Is there a way to modify just `==` (and the other comparisons)? – a06e Jun 29 '15 at 21:28
-
-
`+` was just an example. I also want `-`, `*`, and so on. Moreover, I know that `valarray` has contrived versions of these operators which are more efficient than a naive implementation (I think they use proxy classes to store intermediate results in expressions like `x + y + z` and then evaluate the whole expression together). I would like to take advantage of those. – a06e Jun 29 '15 at 21:31
Do not override the default operator==
use for example this instead:
bool isEqual( const std::valarray< bool >& aResult )
{
bool equals = true;
for ( auto item : aResult )
{
equals &= item;
}
return equals;
}
And then use it:
std::valarray< int > x;
std::valarray< int > y;
bool equals = isEqual( x == y );

- 2,815
- 2
- 24
- 41
-
If I can (can I? how?) override the default `operator==`, why not do it? That would be clearer to read than `isEqual(x==y)`. – a06e Jun 29 '15 at 21:41
-
@becko because the operator is alredy doing half of what you need. On the other hand, if `x!=y` then not all elements have to be compared. Would be interesting to see what would be faster. – 463035818_is_not_an_ai Jun 29 '15 at 21:49
-
@tobi303 both `x==y` and `x!=y` can short-circuit (which would be easy to fix in this answer). – a06e Jun 29 '15 at 21:50
-
@becko I did not mean the operator `!=` but the evaluation of `==` in case x is not equal to y. Of course the same works for `!=`. – 463035818_is_not_an_ai Jun 29 '15 at 21:52
-
@becko as I understand it, in the answer all elements are compared (by the built-in `x==y`). He only shortcircuits the AND of all this results while one could already short-circuit the comparison of the elements (but this would require not to use the built-in `==`) – 463035818_is_not_an_ai Jun 29 '15 at 21:58
-
There can be an `if` in the `for` loop if you like it better. And if the item is false just return false. – p.i.g. Jun 29 '15 at 22:00
-
-
@p.i.g. yes, you can do that, but then you still compare all elements of the valarrays (before you even enter the loop), which is not the most efficient way. – 463035818_is_not_an_ai Jun 30 '15 at 17:42
I agree with the others not to override the ==
operator. The reason is that those operators are the major reason to use a valarray
. If you do not need element-wise operators simply do not use valarray
. Also you might need the original version of the operator at some point so why would you throw it away?
I like p.i.g s solution, but if efficiency is a major concern, I would modify it like this:
#include <utility>
#include <valarray>
template <typename T>
bool isEqual( const std::valarray<T>& x,const std::valarray<T>& b) {
bool equals = true;
for (auto it = std::make_pair(std::begin(x), std::begin(b));it.first != std::end(x);++it.first,++it.second) {
equals &= ((*it.first) == (*it.second));
if (!equals) break;
}
return equals;
}
and use it like this
valarray<T> x,y;
bool b = isEqual(x,y);
By not using the built-in ==
not all elements in the valarrays have to be compared.
PS:
+
was just an example. I also want -, *, and so on. Moreover, I know that valarray has contrived versions of these operators which are more efficient than a naive implementation (I think they use proxy classes to store intermediate results in expressions like x + y + z and then evaluate the whole expression together). I would like to take advantage of those.
Actually, thats interesting and I didnt know about this before. And the conclusion should be: Do not override those operators, otherwise you cannot take advantage of their clever implementations.

- 1,516
- 14
- 21

- 109,796
- 11
- 89
- 185
-
1@Anakhand hum, seems like i didnt test the code at all. Shame on me. Only now I realized that the function compares the elements of the first parameter with elements of the first parameter :/ – 463035818_is_not_an_ai Apr 11 '19 at 13:46
-
If you are decided on "overriding" std::valarray
's operator==
for commodity (instead of writing a named function like in user463035818's answer), you could write a custom "adaptor" class:
template<typename T>
class CustomValArray : public std::valarray<T> {
public:
typedef std::valarray<T> base;
// We need to re-implement any non-default constructors we want to use:
CustomValArray(std::initializer_list<T> init) : base(init) {}
};
/// Accumulation (single bool) comparison
template<typename T>
bool operator==(const CustomValArray<T> &lhs, const CustomValArray<T> &rhs) {
return std::equal(std::begin(lhs), std::end(lhs), std::begin(rhs));
}
If you also wanted to be able to use the original operator==
for std::valarray
, you could do so by writing a named function:
/// Element-wise comparison
template<typename T>
auto elementWiseEqual(const CustomValArray<T> &lhs, const CustomValArray<T> &rhs) {
// We delegate to operator==(const std::valarray<T> &, const std::valarray<T> &)
typedef std::valarray<T> base;
return dynamic_cast<const base &>(lhs) == dynamic_cast<const base &>(rhs);
}
Note: the snippet above uses C++14's automatic return type deduction. If you're on C++11, you should add something like -> decltype(std::valarray<T>() == std::valarray<T>())
to the end of the declarator.
If you choose to do it like this, inheriting directly from std::valarray
, be aware of the possible risks of inheriting from an STL class.
As an alternative, you could have a wrapper class with a std::valarray<T>
private member, and manually delegate any member functions you want to use to std::valarray
.

- 2,838
- 1
- 22
- 50