Morpheus
Morpheus

Reputation: 3523

How to find indices in an std::vector<bool> which are true?

I have say the following bool vector

v = [false ,true, false ,false ,true, false ,false ,true]

I want another vector which contains the indices of v for which the elements are true.

I have the following code:

std::vector<int> nds; //contains the indices
for (const auto &elem : v)
{
    auto idx = &elem - &v[0];
    if (elem)
    {
        nds.push_back(idx);
    }
}

The above seems to work on my MacBook but it is causing the following error on Linux.

src/file.cpp:76:25: error: taking address of temporary [-fpermissive]
                         auto idx = &elem - &v[0];
                                                ^

Is there a better way to find the indices?

P.S. This is just a snippet of some larger code.

Upvotes: 3

Views: 1483

Answers (2)

dfrib
dfrib

Reputation: 73176

Using the range-v3 library, you can use a functional programming style approach to chain the lazy views::enumerate iterator with the lazy views::filter and views::transform view transformations to construct an std::vector<int> of the true-valued (original) indices:

const auto nds = v | views::enumerate 
   | views::filter([](auto p) { return p.second; }) 
   | views::transform([](auto p) { return p.first; }) 
   | to<std::vector<int>>;

DEMO.


Alternatively, replacing the views::transform with views::keys:

const auto nds = v | views::enumerate 
    | views::filter([](auto p){ return p.second; })
    | views::keys
    | to<std::vector<int>>;

DEMO.

Upvotes: 4

Andreas DM
Andreas DM

Reputation: 10998

is there a better way to find the indices?

Use a classical for loop

for (int i = 0; i != v.size(); ++i) {
  if (v[i]) nds.push_back(i);
}

Upvotes: 8

Related Questions