I have a large std::vector<int> a
, but I would like to work only on a subset of it. The idea was to create a std::vector<reference_wrapper<int> > refa
that only contains the said subset (in the mwe, all elements 1< a
< 4). I would then like to pass refa
to functions that expect a std::vector<int>
or std::vector<int>&
as arguments (because I also want to use them with a
). a
can be pretty large and I want to avoid to do the selection multiple times.
Questions
How do I properly pass refa
to the functions? What I want is bar(refa)
and foobar(refa)
to work.
Is there a better way to solve the problem, without changing the functions (too much)?
Code
#include <functional>
#include <iostream>
#include <vector>
int foo(int &a)
{
a++;
return 0;
}
int bar(std::vector<int> &va)
{
for(auto &vaa : va)
vaa++;
return 0;
}
int foobar(std::vector<int> va)
{
for(auto &vaa : va)
vaa++;
return 0;
}
int main()
{
std::vector<int> a= {1, 2, 3, 4, 5};
std::vector<std::reference_wrapper<int> > refa;
//Fill refa
for(auto &aa : a)
{
if(aa>1 && aa<4) refa.push_back(std::ref(aa));
}
//works
// for(auto &aa : refa)
// aa++;
//works
// bar(a);
//works, a unchanged
// foobar(a);
//works
// for(auto &aa : refa)
// foo(aa);
//works
// for(int &aa : refa)
// foo(aa)
// does not work
// conversion from vector<reference_wrapper<int> > to vector<int>& or vector<int> required
bar(refa);
// foobar(refa);
for(auto &aa : a)
std::cout << aa << std::endl;
return 0;
}
Note
int
is only used here to keep the example simple.
I would definitely use iterators especially considering your problem ahead (work on a subset of a vector):
template<class Iterator>
int bar(Iterator begin, Iterator end)
{
for (auto it = begin; it != end; ++it)
(*it)++;
return 0;
}
So that not only you abstract away from the container, but you can also easily pass different iterators from the classical "begin" and "end" iterator to simulate specific ranges:
bar(a.begin() + 2, a.begin() + 4);
For example, with the above code you will visit elements from 1 to 4 (both excluded). And here's the live example.