21

I have a vector of ints that I want to add multiple values too but too many values to add using a lot of push_backs. Is there any method of adding multiple values at the end of a vector. Something along the lines of this:

std::vector<int> values
values += {3, 9, 2, 5, 8, etc};

I found that boost has something like this, but I would like not having to include boost.

#include <boost/assign/std/vector.hpp>

using namespace boost::assign;

{
    std::vector<int> myElements;
    myElements += 1,2,3,4,5;
}

Which seems to be declared like this:

template <class V, class A, class V2>
inline list_inserter<assign_detail::call_push_back<std::vector<V,A> >, V> 
operator+=( std::vector<V, A>& c, V2 v )
{
    return push_back( c )( v );
}

Is there any C++/C++11 way to do this or, if not, how would it be implemented?

David G
  • 94,763
  • 41
  • 167
  • 253
Eejin
  • 770
  • 1
  • 8
  • 29

6 Answers6

37

This should work:

std::vector<int> values;
values.insert( values.end(), { 1, 2, 3, 4 } );
Slava
  • 43,454
  • 1
  • 47
  • 90
8

Perhaps with insert:

values.insert( values.end(),  {3, 9, 2, 5, 8, etc} );

Demo.

Columbo
  • 60,038
  • 8
  • 155
  • 203
4

In order to present as much as possible solutions, this should work too:

for(const auto x : {11, 12, 13, 14})
    v.push_back(x);

Demo.

Tacet
  • 1,411
  • 2
  • 17
  • 32
  • If you know you're going to be increasing the size by N > 1, you should call `v.reserve` to increase the reserved size appropriately before adding the values. Or use `v.insert`, as above. – Paul Price May 12 '21 at 19:20
3

You can just make an operator:

template <class T>
std::vector<T>& operator+=(std::vector<T>& lhs, std::initializer_list<T> l)
{
    lhs.insert(std::end(lhs), l);
    return lhs;
}
David G
  • 94,763
  • 41
  • 167
  • 253
  • 3
    There's an annoying issue with this that I've never really found a good solution to; if you put this function in global namespace and then you try to use it in a namespace where you have defined a completely different `operator+=`, then this function is hidden. To work around this you have to do `using ::operator+=` in any namespace that declares another `operator+=`. This one is not found by ADL since that would only check `namespace std` (and we cannot put this in `namespace std` because user code cannot do that). – M.M Nov 11 '14 at 19:00
  • @MattMcNabb I'm aware of that. I should've added a comment about that. – David G Nov 11 '14 at 19:01
  • 2
    @0x499602D2: It is not too late! – Lightness Races in Orbit Nov 12 '14 at 01:24
3

You can mimic the boost boost::assign behavior

template <typename T> 
class vector_adder 
{
public:
    std::vector<T>& v;
    vector_adder(std::vector<T>& v):v(v)
    {  }

    vector_adder& operator,(const T& val)
    {  
       v.push_back(val);
       return *this;
    }
};

template <typename T> 
vector_adder<T> operator+=(std::vector<T>& v,const T& x)
{
    return vector_adder<T>(v),x;
}

Then,

 std::vector<int> v {1,2,3,4};
 v += 11,12,13,14 ;

See here

P0W
  • 46,614
  • 9
  • 72
  • 119
1

You can do it by using the insert member function, as such:

vector<int> v; 
int myarr[] {1, 2, 4, 5, 5, 6, 6, 8}; //brace initialization with c++11

v.insert(v.end(), myarr, myarr+8);

There was a previous answer that omitted the middle argument in the insert parameters, but that one does not work. There are several formats to follow for the insert method, which can be found here and the code snippet I wrote practically follows this format:

vectorName.insert(postion to start entering values, first value to enter, how many values to enter)

Note: That the last two arguments (i.e. myarr, myarr+8) use pointer arithmetics. myarr is the address in memory of the first element in the array, and the second value is the address of the 8th element. You can read about pointer arithmetic here.

Hope that helps!

nopenopenope
  • 33
  • 11