What is the easiest way to initialize a std::vecto

2018-12-31 08:11发布

I can create an array and initialize it like this:

int a[] = {10, 20, 30};

How do I create a std::vector and initialize it similarly elegant?

The best way I know is:

std::vector<int> ints;

ints.push_back(10);
ints.push_back(20);
ints.push_back(30);

Is there a better way?

25条回答
美炸的是我
2楼-- · 2018-12-31 08:25

In C++0x you will be able to do it in the same way that you did with an array, but not in the current standard.

With only language support you can use:

int tmp[] = { 10, 20, 30 };
std::vector<int> v( tmp, tmp+3 ); // use some utility to avoid hardcoding the size here

If you can add other libraries you could try boost::assignment:

vector<int> v = list_of(10)(20)(30);

To avoid hardcoding the size of an array:

// option 1, typesafe, not a compile time constant
template <typename T, std::size_t N>
inline std::size_t size_of_array( T (&)[N] ) {
   return N;
}
// option 2, not typesafe, compile time constant
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))

// option 3, typesafe, compile time constant
template <typename T, std::size_t N>
char (&sizeof_array( T(&)[N] ))[N];    // declared, undefined
#define ARRAY_SIZE(x) sizeof(sizeof_array(x))
查看更多
爱死公子算了
3楼-- · 2018-12-31 08:25

B. Stroustrup describes a nice way to chain operations in 16.2.10 Selfreference on page 464 in the C++11 edition of the Prog. Lang. where a function returns a reference, here modified to a vector. This way you can chain like v.pb(1).pb(2).pb(3); but may be too much work for such small gains.

#include <iostream>
#include <vector>

template<typename T>
class chain
{
private:
    std::vector<T> _v;
public:
    chain& pb(T a) {
        _v.push_back(a);
        return *this;
    };
    std::vector<T> get() { return _v; };
};

using namespace std;

int main(int argc, char const *argv[])
{
    chain<int> v{};

    v.pb(1).pb(2).pb(3);

    for (auto& i : v.get()) {
        cout << i << endl;
    }

    return 0;
}

1
2
3

查看更多
泪湿衣
4楼-- · 2018-12-31 08:26

If you don't want to use boost, but want to enjoy syntax like

std::vector<int> v;
v+=1,2,3,4,5;

just include this chunk of code

template <class T> class vector_inserter{
public:
    std::vector<T>& v;
    vector_inserter(std::vector<T>& v):v(v){}
    vector_inserter& operator,(const T& val){v.push_back(val);return *this;}
};
template <class T> vector_inserter<T> operator+=(std::vector<T>& v,const T& x){
    return vector_inserter<T>(v),x;
}
查看更多
墨雨无痕
5楼-- · 2018-12-31 08:27

you can do that using boost::assign.

vector<int> values;  
values += 1,2,3,4,5,6,7,8,9;

detail here

查看更多
还给你的自由
6楼-- · 2018-12-31 08:29

If the array is:

int arr[] = {1, 2, 3};
int len = (sizeof(arr)/sizeof(arr[0])); // finding length of array
vector < int > v;
std:: v.assign(arr, arr+len); // assigning elements from array to vector 
查看更多
刘海飞了
7楼-- · 2018-12-31 08:31

If your compiler supports C++11, you can simply do:

std::vector<int> v = {1, 2, 3, 4};

This is available in GCC as of version 4.4. Unfortunately, VC++ 2010 seems to be lagging behind in this respect.

Alternatively, the Boost.Assign library uses non-macro magic to allow the following:

#include <boost/assign/list_of.hpp>
...
std::vector<int> v = boost::assign::list_of(1)(2)(3)(4);

Or:

#include <boost/assign/std/vector.hpp>
using namespace boost::assign;
...
std::vector<int> v;
v += 1, 2, 3, 4;

But keep in mind that this has some overhead (basically, list_of constructs a std::deque under the hood) so for performance-critical code you'd be better off doing as Yacoby says.

查看更多
登录 后发表回答