1

So, I've been doing this when concatenating two collections (say, a std::vector with a std::array):

std::vector<Foo> foos;
std::array<Foo,12> toAdd = { /* value list */ };

for(....)
{
    foos.insert(end(foos),begin(toAdd),end(toAdd));
}

but, it just occurred to me to do this:

template<typename T1, typename T2>
void append(T1 &target, T2 &source)
{
    target.insert(end(target),begin(source),end(source));
}


/// ....


append(foos,toAdd);

Is there an equivalent routine already in the STL that I haven't run across?

In this case, the toAdd array is initialized with a specific pattern of values that is difficult to generate in code, and is a bit lengthy. Using the array initializer instead of a lot of ::push_back() calls is much clearer in code. Otherwise, I'd just vector::reserve() to up the size, and put everything directly into the vector.

Ali
  • 56,466
  • 29
  • 168
  • 265
3Dave
  • 28,657
  • 18
  • 88
  • 151
  • There's nothing like your `append`, no. But TBH I wouldn't use yours. I very rarely concatenate containers and would rather use the standard `.insert(...)`. On the rare occasion I have in my memory, I've wanted to _move_ the elements. Also I don't understand your last paragraph: you already established the correct way is with `.insert` - why are you comparing to `reserve` + `push_back` in a loop? – David Feb 14 '14 at 18:45
  • If you're doing this to initialize a vector, in C++11 you can just do `vector v = {1, 2, 3, 4};` – David Feb 14 '14 at 18:48
  • @Dave this is in a tessellation loop, and doesn't lend itself to that sort of initialization (for the target collection). If I was only doing it once, that would make sense. I was referring to building the new list as a comma-delimited set rather than individual push_back() calls for each element that has to be inserted (which just looks messy and overly verbose). – 3Dave Feb 14 '14 at 18:55
  • @Dave also, you're right about `move` vs copy. Off to fix THAT one now... – 3Dave Feb 14 '14 at 18:59
  • [make_move_iterator](http://en.cppreference.com/w/cpp/iterator/make_move_iterator) – David Feb 14 '14 at 19:05
  • @Dave found that. Of course, that makes the `::insert` even more verbose, which the initial template function was meant to avoid. But, the fact that there's not an equivalent `append` in the STL answers my question. – 3Dave Feb 14 '14 at 19:17
  • @DavidLively Thanks. And I apologize for misunderstanding your real question on the first read and marking it as a duplicate. – Ali Feb 14 '14 at 21:07
  • If you actually do this, I suggest you take a Source&&, moving if Source&& is an rvalue reference and copying if it's not... that will take some SFINAE to pull off, I think. – David Feb 14 '14 at 21:27

1 Answers1

1

Perhaps the most generic way is:

template <typename SrcCont, typename DestCont>
void append(const SrcCont& source, DestCont& destination) {
    std::copy(std::begin(source), std::end(source), std::back_inserter(destination));
}

Example:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <list>

template <typename SrcCont, typename DestCont>
void append(const SrcCont& source, DestCont& destination) {
    std::copy(std::begin(source), std::end(source), std::back_inserter(destination));
}

int main() {

  std::list<int> li{1, 2, 3};

  auto src = {4, 5, 6};

  append(src, li);

  for (int i : li)
    std::cout << i << '\n';
}

This prints:

1
2
3
4
5
6

Ali
  • 56,466
  • 29
  • 168
  • 265
  • What's the difference between using `std::copy` and `std::insert`? – 3Dave Feb 17 '14 at 16:06
  • @DavidLively Is there a `std::insert`? `std::copy` is a free function and there is `std::vector::insert()` which is a member function of `std::vector`. – Ali Feb 17 '14 at 16:14
  • @DavidLively As a side note: I will revise this answer because it doesn't work if you want to append the vector to itself. It is not yet clear to me how it is best done in a generic way (for *any* container), see [Append a copy of std::vector to the end of itself](http://stackoverflow.com/q/21802757/341970) for discussion. Please give me some time with this revision and in the meantime, make sure you are not appending the container to itself. – Ali Feb 17 '14 at 16:17