lynn
lynn

Reputation: 10784

Converting valarray<bool> to valarray<int>

I'm trying to convert a valarray<bool> to a valarray<int> of 0s and 1s.

I hoped something like this would work (invoking integral promotion with unary +, as works on a single bool):

#include <iostream>
#include <valarray>

int main() {
    std::valarray<int> xx = { 1, 2, 3, 4, 5 };
    std::valarray<int> yy = { 5, 4, 3, 2, 1 };
    std::valarray<int> zz = +(xx < yy);
    std::cout << zz[0] << std::endl;
    return 0;
}

It seems like some compilers like this, but others don't. The ones that don't output something like:

<source>:7:24: error: no viable conversion from '_Expr<_UnClos<std::__unary_plus, std::_Expr, std::__detail::_BinClos<std::__less, _ValArray, _ValArray, int, int>>, std::_Expr<std::__detail::_BinClos<std::__less, _ValArray, _ValArray, int, int>, bool>::value_type>' (aka '_Expr<_UnClos<std::__unary_plus, std::_Expr, std::__detail::_BinClos<std::__less, _ValArray, _ValArray, int, int>>, bool>') to 'std::valarray<int>'
    std::valarray<int> zz = +(xx < yy);
                       ^    ~~~~~~~~~~

I can use the "mask indexing" to write:

    std::valarray<int> zz = 0 * xx; zz[xx < yy] = 1;

But this is a little cumbersome, and I would like to have a single expression.

Converting a single bool to an int is easy, but it seems that .apply() is not allowed to change the type of the contents, so I can't simply map such a conversion over the array.

Is there a simpler way?

Upvotes: 1

Views: 390

Answers (1)

ArashV
ArashV

Reputation: 84

First, subtract yy from xx and let the resulted valarray< int > use apply() in order to return 0 or 1 for each element:

std::valarray<int> zz = (xx - yy).apply([](int x) {return x < 0; });

Upvotes: 0

Related Questions