2012-01-18 5 views
167

Possible Duplicate:
C++: Easiest way to initialize an STL vector with hardcoded elementsКак инициализировать вектор в C++

Я хочу, чтобы инициализировать вектор, как мы делаем в случае массива.

Пример

int vv[2] = {12, 43}; 

Но когда я делаю это так,

vector<int> v(2) = {34, 23}; 

ИЛИ

vector<int> v(2); 
v = {0, 9}; 

он дает ошибку:

expected primary-expression before ‘{’ token

И

error: expected ‘,’ or ‘;’ before ‘=’ token

соответственно.

+3

Там же [как-инициализировать 'константный зЬй :: вектор ' как массив переменного тока] (http://stackoverflow.com/questions/231491/how- чтобы инициализировать-Const-stdvectort-подобный-ас-массив/254143). – Shadow2531

+0

Вы должны включить поддержку C++ 11 в своем компиляторе, например. 'g ++ -std = C++ 11 your_file.cc'. Затем вы можете использовать конструктор списка инициализаторов потока (последний элемент в [этой ссылке] (http://en.cppreference.com/w/cpp/container/vector/vector)) –

+1

Не обман - другой вопрос как это сделать со старым C++, ответ WTF заключается в том, как это сделать сейчас –

ответ

234

С стандарта нового C++ (может потребоваться специальные флаги быть включен на ваш компилятор), вы можете просто сделать:

std::vector<int> v { 34,23 }; 
// or 
// std::vector<int> v = { 34,23 }; 

Или даже:

std::vector<int> v(2); 
v = { 34,23 }; 

На компиляторов, которые не поддерживают эта функция (списки инициализаторов), но вы можете эмулировать ее с помощью массива:

int vv[2] = { 12,43 }; 
std::vector<int> v(&vv[0], &vv[0]+2); 

Или, для случая назначение существующего вектора:

int vv[2] = { 12,43 }; 
v.assign(&vv[0], &vv[0]+2); 

Как Джеймс Kanze предположил, что это надежнее иметь функции, которые дают вам начало и конец массива:

template <typename T, size_t N> 
T* begin(T(&arr)[N]) { return &arr[0]; } 
template <typename T, size_t N> 
T* end(T(&arr)[N]) { return &arr[0]+N; } 

И тогда вы можете сделать это без повторить размер всего:

int vv[] = { 12,43 }; 
std::vector<int> v(begin(vv), end(vv)); 
+15

Или просто: std :: vector v (vv, vv + 2); –

+8

Или более надежно: 'std :: vector v (begin (w), end (w);'. 'Begin 'и' end' являются стандартными в C++ 11 (но тогда они вам не нужны) , но должен быть в вашем наборе инструментов. –

+1

Я знаю, что это старый вопрос, но что именно вы здесь делаете: 'std :: vector v (& vv [0], & vv [0] +2);'?Я вижу, что вы создаете вектор с пространством для значений '& vv [0]' (который будет адресом памяти) и заполняете каждое пространство в векторе '& vv [0] + 2' ... Это будет использовать конструктор 2 на этой странице: http://en.cppreference.com/w/cpp/container/vector/vector, не поставляя третий аргумент, который по умолчанию используется для Allocator(). Я знаю, что чего-то не хватает. –

27

Вы также можете сделать так:

template <typename T> 
class make_vector { 
public: 
    typedef make_vector<T> my_type; 
    my_type& operator<< (const T& val) { 
    data_.push_back(val); 
    return *this; 
    } 
    operator std::vector<T>() const { 
    return data_; 
    } 
private: 
    std::vector<T> data_; 
}; 

И использовать его как это:

std::vector<int> v = make_vector<int>() << 1 << 2 << 3; 
+0

Можно ли переместить * data_ * в * v * вместо вызова конструктора копирования? – Per

+1

Привет, Пер! Я полагаю, что вам это нравится (предупреждение, непроверено): operator std :: vector &&() { return std :: move (data_); } –

Смежные вопросы