Как проще всего инициализировать std :: vector жестко закодированными элементами? - PullRequest
561 голосов
/ 10 февраля 2010

Я могу создать массив и инициализировать его так:

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

Как мне создать std::vector и инициализировать его так же элегантно?

Лучший способ, которым я знаю, это:

std::vector<int> ints;

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

Есть ли лучший способ?

Ответы [ 25 ]

588 голосов
/ 10 февраля 2010

Если ваш компилятор поддерживает C ++ 11, вы можете просто сделать:

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

Доступно в GCC начиная с версии 4.4 . К сожалению, VC ++ 2010 в этом отношении, похоже, отстает.

В качестве альтернативы библиотека Boost.Assign использует немакро-магию, чтобы разрешить следующее:

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

Или:

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

Но имейте в виду, что это имеет некоторые накладные расходы (в основном, list_of создает std::deque под капотом), поэтому для кода, критичного к производительности, вам будет лучше делать, как говорит Якоби.

519 голосов
/ 10 февраля 2010

Одним из методов будет использование массива для инициализации вектора

static const int arr[] = {16,2,77,29};
vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) );
76 голосов
/ 10 февраля 2010

В C ++ 0x вы сможете сделать это так же, как с массивом, но не в текущем стандарте.

Вы можете использовать только языковую поддержку:

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

Если вы можете добавить другие библиотеки, вы можете попробовать boost :: assignment:

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

Чтобы избежать жесткого кодирования размера массива:

// 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))
72 голосов
/ 14 июня 2018

Если можете, используйте современный C ++ [11,14,17, ...] путь:

std::vector<int> vec = {10,20,30};

Старый способ циклического перебора массива переменной длины или использование sizeof() действительно ужасен для глаз и совершенно не нужен с точки зрения умственных издержек. Тьфу.

56 голосов
/ 08 октября 2013

В C ++ 11:

#include <vector>
using std::vector;
...
vector<int> vec1 { 10, 20, 30 };
// or
vector<int> vec2 = { 10, 20, 30 };

Использование boost list_of:

#include <vector>
#include <boost/assign/list_of.hpp>
using std::vector;
...
vector<int> vec = boost::assign::list_of(10)(20)(30);

Использование форсированного назначения:

#include <vector>
#include <boost/assign/std/vector.hpp>
using std::vector;
...
vector<int> vec;
vec += 10, 20, 30;

Обычный STL:

#include <vector>
using std::vector;
...
static const int arr[] = {10,20,30};
vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) );

Обычный STL с общими макросами:

#include <vector>
#define ARRAY_SIZE(ar) (sizeof(ar) / sizeof(ar[0])
#define ARRAY_END(ar) (ar + ARRAY_SIZE(ar))
using std::vector;
...
static const int arr[] = {10,20,30};
vector<int> vec (arr, ARRAY_END(arr));

Обычный STL с макросом инициализатора вектора:

#include <vector>
#define INIT_FROM_ARRAY(ar) (ar, ar + sizeof(ar) / sizeof(ar[0])
using std::vector;
...
static const int arr[] = {10,20,30};
vector<int> vec INIT_FROM_ARRAY(arr);
52 голосов
/ 03 апреля 2011

Просто подумал, что я добавлю свои 0,02 доллара.Я склонен объявлять это:

template< typename T, size_t N >
std::vector<T> makeVector( const T (&data)[N] )
{
    return std::vector<T>(data, data+N);
}

в служебном заголовке где-то, и тогда все, что требуется:

const double values[] = { 2.0, 1.0, 42.0, -7 };
std::vector<double> array = makeVector(values);

Но я не могу дождаться C ++ 0x.Я застрял, потому что мой код также должен компилироваться в Visual Studio.Boo.

34 голосов
/ 03 августа 2016

До C ++ 11:

Метод 1 =>

vector<int> v(arr, arr + sizeof(arr)/sizeof(arr[0]));
vector<int>v;

Метод 2 =>

 v.push_back(SomeValue);

C ++ 11 и ниже также возможно

vector<int>v = {1, 3, 5, 7};
27 голосов
/ 12 декабря 2014

Начиная с:

int a[] = {10, 20, 30}; //i'm assuming a is just a placeholder

Если у вас нет компилятора C ++ 11 и вы не хотите использовать boost:

const int a[] = {10, 20, 30};
const std::vector<int> ints(a,a+sizeof(a)/sizeof(int)); //make it const if you can

Если у вас нет компилятора C ++ 11 и вы можете использовать boost:

#include <boost/assign.hpp>
const std::vector<int> ints = boost::assign::list_of(10)(20)(30);

Если у вас есть компилятор C ++ 11:

const std::vector<int> ints = {10,20,30};
21 голосов
/ 24 января 2013

Самый простой способ сделать это:

vector<int> ints = {10, 20, 30};
19 голосов
/ 28 июня 2017

Для инициализации вектора -

vector<int> v = {10,20,30}

можно сделать, если у вас есть компилятор c ++ 11.

Иначе, вы можете получить массив данных и затем использовать цикл for.

int array[] = {10,20,30}
for(unsigned int i=0; i<sizeof(array)/sizeof(array[0]); i++)
{
     v.push_back(array[i]);
}

Помимо этого, есть несколько других способов, описанных выше, с использованием некоторого кода. На мой взгляд, эти способы легко запомнить и быстро написать.

...