2

I have a situation where I have 2 vectors:

vector<char> v1 = {1,3,4}
vector<char> v2 = {4,5,6}

which in reality can grow very large.

What is required of these vectors is that they are each passed into a function with signature:

template<class supports_[]_operator>
double absolutely_awesome_function(const supports_[]_operator& v)

However, i also need the concatenated vector to be passed to this function.

i.e.

v3= {1,3,4,4,5,6}

at which point it is never used again.

Now, there are obviously, a number of ways to simply make a new object and pass that in, however as I said the vectors are large and the 'absolutely_awesome_function' is very fast, so this is obviously not ideal.

I thought about making an object like so:

template<class T>
class AmIAVector{
    AmIAVector(const T& vec_1, const T& vec_2)

    auto operator [](int i) const    {return 'an index into either vec1 or vec2'}
}

But is there a better way / does something already exist for this

user3684792
  • 2,542
  • 2
  • 18
  • 23
  • `template`: I would slap my colleagues for doing such things ... – Torbjörn Aug 19 '16 at 13:04
  • 5
    Maybe the `absolutely_awesome_function` should take iterators as most stl algos do, then you can provide suitable begin and end iterators. Something like `boost::join` might be good too: http://stackoverflow.com/questions/981186/chain-iterator-for-c, or http://stackoverflow.com/questions/6747987/writing-an-iterator-that-makes-several-containers-look-as-one – doctorlove Aug 19 '16 at 13:04
  • @ torbjorn it is for clarity only – user3684792 Aug 19 '16 at 13:04
  • doctorlove make an answer and i'll accept. ty – user3684792 Aug 19 '16 at 13:05
  • 3
    @Torbjörn - no need to slap anyone. The compiler will do it for you. – Pete Becker Aug 19 '16 at 13:17

2 Answers2

3

There are several possible solutions to this.

Since absolutely_awesome_function specifically takes a vector you are stuck.

With a redesign, it could take iterators as most stl algorithms do, then you can provide suitable begin and end iterators.

Something like boost::join will just work.

boost::join(v1, v2)

Related questions: stackoverflow.com/questions/981186/chain-iterator-for-c, or Writing an iterator that makes several containers look as one

Community
  • 1
  • 1
doctorlove
  • 18,872
  • 2
  • 46
  • 62
  • 2
    The OP is not really stuck even in this case. It's trivial to provide a wrapper with `operator []` over an iterator pair. Basically a joined range; I believe those are in Boost as well. – Angew is no longer proud of SO Aug 19 '16 at 13:13
2

range-v3 allows that:

const std::vector<int> v1{4, 8, 15};
const std::vector<int> v2{16, 23, 42};
const auto view = ranges::view::concat(v1, v2);

for (const auto& e : view) {
    std::cout << e << " ";   
}
std::cout << std::endl;
std::cout << view[5] << std::endl;

Demo

Jarod42
  • 203,559
  • 14
  • 181
  • 302