Cách dễ nhất để khởi tạo một std :: vector với các phần tử được mã hóa cứng là gì?


612

Tôi có thể tạo một mảng và khởi tạo nó như thế này:

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

Làm thế nào để tôi tạo std::vectorvà khởi tạo nó thanh lịch tương tự?

Cách tốt nhất tôi biết là:

std::vector<int> ints;

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

Có cách nào tốt hơn?


1
nếu bạn sẽ không thay đổi kích thước của int sau khi khởi tạo, hãy xem xét sử dụng mảng tr1.
zr.

@zr, bạn có tò mò không ... nếu tôi cần kích thước cố định, tôi có thể không sử dụng các mảng cũ đơn giản không? Nhìn vào mảng tr1 ngay bây giờ ...
Agnel Kurian

2
tr1::arraylà hữu ích vì các mảng thông thường không cung cấp giao diện của các thùng chứa STL
Manuel

Thay đổi tiêu đề để làm cho câu hỏi này rõ ràng là một câu hỏi C ++ 03. Có vẻ dễ hơn là trải qua và sửa tất cả các câu trả lời để có ý nghĩa với C ++ tiêu chuẩn mới.
TED

Đây được gọi là khởi tạo danh sách .
Alan Dawkins

Câu trả lời:


548

Một phương pháp sẽ là sử dụng mảng để khởi tạo vectơ

static const int arr[] = {16,2,77,29};
vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) );

7
@Agnel Nó sẽ hoạt động tốt mà không cần statichoặc const, tuy nhiên cả hai đều làm cho nó rõ ràng hơn về cách sử dụng nó và cho phép trình biên dịch thực hiện tối ưu hóa bổ sung.
Yacoby

68
Tôi đã không hạ thấp điều này, nhưng tôi đã bị cám dỗ. Chủ yếu là vì điều này giúp bạn tiết kiệm gần như không có gì ngoài việc sử dụng mảng khởi tạo ở vị trí đầu tiên. Tuy nhiên, đó thực sự là lỗi của C ++, không phải của bạn.
TED

2
Bạn có thể giải thích lý do tại sao bạn sử dụng các tham số đó khi xác định vec tơ vecni.
DomX23

13
sizeof (mảng) là một trong số ít trường hợp ngoại lệ cho phép lấy tổng kích thước của các phần tử của mảng và KHÔNG phải kích thước con trỏ mảng. Vì vậy, về cơ bản, anh ta đang sử dụng vectơ (con trỏ_to_first_element, con trỏ_to_first_element + size_in_bytes_of_the_whole_array / size_of_one_element) đó là: vectơ (con trỏ_to_first_element, con trỏ Loại đã được cung cấp với <int>, vì vậy vectơ biết một phần tử là bao nhiêu. Hãy nhớ rằng các trình vòng lặp có thể được coi là các con trỏ, vì vậy về cơ bản bạn đang sử dụng hàm tạo (vectơ bắt đầu, kết thúc vòng lặp)
Johnny Pauling

11
@TED: Đôi khi bạn cần sửa đổi vectơ kết quả. Ví dụ, bạn có thể cần phải luôn có một số tham số mặc định và đôi khi thêm một vài tùy chỉnh cho chúng.
DarkWanderer

642

Nếu trình biên dịch của bạn hỗ trợ C ++ 11, bạn chỉ cần làm:

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

Điều này có sẵn trong GCC kể từ phiên bản 4.4 . Thật không may, VC ++ 2010 dường như bị tụt lại phía sau về mặt này.

Ngoài ra, thư viện Boost.Assign sử dụng phép thuật phi vĩ mô để cho phép những điều sau đây:

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

Hoặc là:

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

Nhưng hãy nhớ rằng điều này có một số chi phí chung (về cơ bản, list_ofxây dựng một phần std::dequedưới) vì vậy đối với mã quan trọng về hiệu năng, bạn nên làm tốt hơn như Yacoby nói.


Vì các vectơ là tự kích thước, nên có thể khởi tạo nó là trống không? Giống như trong các nhà xây dựng : this->vect = {};?
Azurespot

3
@Azurespot Bạn chỉ có thể khởi tạo nó và nó sẽ trống:std::vector<T> vector;
Luke

2
Chỉ trong trường hợp ai đó có thể tò mò std::vector<int> v = {1, 2, 3, 4};, vector initializer list constructorsẽ được gọi cho kiểu khởi tạo này, tài liệu của nó có thể được tìm thấy trong C++ 11phần .
simomo

103

Nếu bạn có thể, hãy sử dụng cách hiện đại C ++ [11,14,17, ...]:

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

Cách thức cũ để lặp lại một mảng có độ dài thay đổi hoặc sử dụng sizeof()thực sự khủng khiếp trên mắt và hoàn toàn không cần thiết về mặt tinh thần. Kinh quá.


2
Công bằng mà nói, đây ban đầu là một câu hỏi của C ++ 03, nhưng tôi hy vọng rằng mọi người / công ty sẽ áp dụng các tiêu chuẩn mới. C ++ vẫn cần triển khai mảng có độ dài thay đổi (VLA) trong thư viện chuẩn tương tự như những gì có sẵn trong Eigen và Boost.
Adam Erickson

Thật không may, cách tiếp cận này có vấn đề trong một số trường hợp, ví dụ open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1467 . Kinh quá.
Các cuộc đua nhẹ nhàng trong quỹ đạo

Nếu "khởi tạo danh sách tổng hợp từ một đối tượng cùng loại" là vấn đề của bạn, thì có lẽ có vấn đề lớn hơn trong cơ sở mã của bạn ... Tôi có thể nghĩ rằng không có ứng dụng nào có thể biện minh cho các vấn đề gỡ lỗi.
Adam Erickson

77

Trong C ++ 0x, bạn sẽ có thể làm điều đó giống như cách bạn đã làm với một mảng, nhưng không phải trong tiêu chuẩn hiện tại.

Chỉ với hỗ trợ ngôn ngữ, bạn có thể sử dụng:

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

Nếu bạn có thể thêm các thư viện khác, bạn có thể thử boost :: gán:

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

Để tránh mã hóa kích thước của một mảng:

// 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))

Tất nhiên tôi đã không downvote nhưng dù sao tôi cũng có một câu hỏi: khi nào thì kích thước của một mảng không phải là hằng số thời gian biên dịch? Tức là, trong trường hợp nào bạn sẽ sử dụng giải pháp đầu tiên trong đoạn trích thứ hai của mình so với giải pháp thứ ba?
Manuel

4
@Manuel, kích thước của mảng là một phần của kiểu và vì vậy nó là hằng số thời gian biên dịch. Bây giờ, tùy chọn 1 sử dụng hằng số thời gian biên dịch 'N' làm giá trị trả về cho hàm. Sự trở lại của một hàm không phải là thời gian biên dịch, mà là giá trị thời gian chạy, ngay cả khi nó có thể sẽ được nội tuyến dưới dạng giá trị không đổi tại nơi gọi. Sự khác biệt là bạn không thể làm: int another[size_of_array(array)]trong khi bạn có thể làm int another[ARRAY_SIZE(array)].
David Rodríguez - dribeas

1
Trong tùy chọn 3: Tôi không thực sự hiểu ý bạn là gì với "khai báo, không xác định"? Vì vậy, biến sẽ không mất thêm bộ nhớ?
To1ne

1
@ To1ne thực sự là một khai báo hàm, không phải là một biến. Lý do cho hoặc xác định nó là vì chúng ta không thực sự muốn hàm cho bất kỳ thứ gì khác ngoài sizeofbiểu thức không cần định nghĩa. Trong khi bạn thực sự có thể cung cấp một định nghĩa, để thực hiện đúng nó sẽ yêu cầu phân bổ tĩnh của một mảng và trả về một tham chiếu cho nó, và câu hỏi tiếp theo sẽ là điều gì có ý nghĩa như các giá trị cho mảng? (Cũng lưu ý rằng điều này có nghĩa là một mảng trên mỗi loại kết hợp / kích thước của tính năng tức thời của hàm!) Vì không sử dụng hợp lý cho nó, tôi muốn tránh nó.
David Rodríguez - dribeas

1
@mhd: Bạn không thể tạo một mảng trống trong ngôn ngữ. 'int mảng [0] = {};' không phải là mã C ++ hợp lệ. Nhưng bạn đã đúng rằng nếu bạn muốn khởi tạo một vectơ trống và một vectơ không trống, bạn sẽ phải sử dụng các cấu trúc khác nhau. Vì C ++ 11, đây không phải là vấn đề vì bạn có thể sử dụng hàm tạo danh sách khởi tạo
David Rodríguez - dribeas

61

Trong C ++ 11:

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

Sử dụng boost list_of:

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

Sử dụng boost gán:

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

STL thông thường:

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

STL thông thường với các macro chung:

#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 thông thường với macro khởi tạo vector:

#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);

2
C ++ 11 cũng hỗ trợ std::beginstd::endcho mảng, vì vậy một vectơ cũng có thể được khởi tạo như thế nào static const int arr[] = {10,20,30}; vector<int> vec(begin(arr), end(arr));.
Jaege

54

Chỉ cần nghĩ rằng tôi đã ném 0,02 đô la của tôi. Tôi có xu hướng tuyên bố điều này:

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

trong một tiêu đề tiện ích ở đâu đó và sau đó tất cả những gì cần thiết là:

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

Nhưng tôi không thể đợi C ++ 0x. Tôi bị kẹt vì mã của tôi cũng phải biên dịch trong Visual Studio. Boo.


1
Kỹ thuật này cũng có thể được sử dụng để quá tải một hàm để chấp nhận một mảng với kích thước được gõ.
Andres Riofrio

4
Bạn có thể giải thích const T (&data)[N]một phần? Làm thế nào là kích thước của mảng suy ra trong cuộc gọi của bạn makeVector(values)?
Patryk

36

Trước C ++ 11:

Phương pháp 1 =>

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

Phương pháp 2 =>

 v.push_back(SomeValue);

C ++ 11 trở đi bên dưới cũng có thể

vector<int>v = {1, 3, 5, 7};

28

Bắt đầu với:

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

Nếu bạn không có trình biên dịch C ++ 11 và bạn không muốn sử dụng boost:

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

Nếu bạn không có trình biên dịch C ++ 11 và có thể sử dụng boost:

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

Nếu bạn có trình biên dịch C ++ 11:

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

22

Đối với khởi tạo véc tơ -

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

có thể được thực hiện nếu bạn có trình biên dịch c ++ 11.

Khác, bạn có thể có một mảng dữ liệu và sau đó sử dụng một vòng lặp for.

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

Ngoài những cách này, có nhiều cách khác được mô tả ở trên bằng cách sử dụng một số mã. Theo tôi, những cách này rất dễ nhớ và nhanh chóng để viết.



16

Tôi xây dựng giải pháp của riêng tôi bằng cách sử dụng va_arg. Giải pháp này tuân thủ C ++ 98.

#include <cstdarg>
#include <iostream>
#include <vector>

template <typename T>
std::vector<T> initVector (int len, ...)
{
  std::vector<T> v;
  va_list vl;
  va_start(vl, len);
  for (int i = 0; i < len; ++i)
    v.push_back(va_arg(vl, T));
  va_end(vl);
  return v;
}

int main ()
{
  std::vector<int> v = initVector<int> (7,702,422,631,834,892,104,772);
  for (std::vector<int>::const_iterator it = v.begin() ; it != v.end(); ++it)
    std::cout << *it << std::endl;
  return 0;
}

Bản giới thiệu


14

Nếu trình biên dịch của bạn hỗ trợ các macro Variadic (đúng với hầu hết các trình biên dịch hiện đại), thì bạn có thể sử dụng macro sau đây để biến khởi tạo vector thành một lớp lót:

#define INIT_VECTOR(type, name, ...) \
static const type name##_a[] = __VA_ARGS__; \
vector<type> name(name##_a, name##_a + sizeof(name##_a) / sizeof(*name##_a))

Với macro này, bạn có thể xác định một vectơ khởi tạo với mã như thế này:

INIT_VECTOR(int, my_vector, {1, 2, 3, 4});

Điều này sẽ tạo ra một vectơ mới của ints có tên my_vector với các phần tử 1, 2, 3, 4.


13

Nếu bạn không muốn sử dụng boost, nhưng muốn tận hưởng cú pháp như

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

chỉ bao gồm đoạn mã này

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;
}

1
Tôi chưa thể tìm ra cách sử dụng mã này, nhưng nó có vẻ thú vị.
Daniel Buckmaster

Nó giống như một trong những nhận xét ở trên. Chỉ cần quá tải toán tử + = và dấu phẩy. Đặt dấu ngoặc đơn cho rõ ràng: ((((v+=1),2),3),4),5) Đây là cách nó hoạt động: Đầu tiên, vector<T> += Ttrả về một vector_inserter cho phép gọi nó viđóng gói vectơ gốc sau đó vi,Tthêm T vào vectơ gốc viđóng gói và tự trả về để chúng ta có thể làm vi,Tlại.
Piti Ongmongkolkul

mã này đã không hoạt động chính xác trên gcc 4.2.1 tôi nghĩ vì trả về tham chiếu cho một biến cục bộ bên trong toán tử + = nhưng ý tưởng là tuyệt vời. tôi đã chỉnh sửa mã và xuất hiện thêm một constructor sao chép. lưu lượng bây giờ -> + = -> ctor -> dấu phẩy -> sao chép -> dtor -> dấu phẩy ...... -> dấu phẩy -> dtor.
Yevhen

Có lẽ tôi đã quá tải << thay vì + =. Ít nhất << đã có quy tắc hiệu ứng phụ mơ hồ vì dịch chuyển bit và cout
Speed8ump

11

Trong C ++ 11:

static const int a[] = {10, 20, 30};
vector<int> vec (begin(a), end(a));

21
Nếu bạn đang sử dụng C ++ 11, bạn cũng có thể sử dụng cách tiếp cận trực tiếp - vector<int> arr = {10, 20, 30};.
Bernhard Barker

Trên thực tế tôi đã có một int [] (một số C lib) đến và muốn đẩy vào một vectơ (C ++ lib). Câu trả lời này có ích, phần còn lại thì không ;-)
Tinh vân

10

bạn có thể làm điều đó bằng cách sử dụng boost :: gán.

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

chi tiết tại đây


19
Tôi đã không thấy một trường hợp tồi tệ hơn của việc lạm dụng quá tải trong một thời gian dài. Liệu có giải quyết được +=1,2,3,4 .. đến hết các giá trị hay không, hoặc thêm 1 vào phần tử thứ 1, 2 cho phần tử thứ 2, 3 cho phần tử thứ 3 (như cú pháp như thế này trong MATLAB- như ngôn ngữ)
bobobobo

10

Một câu hỏi trùng lặp gần đây hơn có câu trả lời này của Viktor Sehr . Đối với tôi, nó nhỏ gọn, hấp dẫn trực quan (có vẻ như bạn đang 'đẩy' các giá trị vào), không yêu cầu c ++ 11 hoặc mô-đun của bên thứ ba và tránh sử dụng biến phụ (bằng văn bản). Dưới đây là cách tôi đang sử dụng nó với một vài thay đổi. Tôi có thể chuyển sang mở rộng chức năng của vectơ và / hoặc va_arg trong phần mở đầu trong tương lai.


// Based on answer by "Viktor Sehr" on Stack Overflow
// https://stackoverflow.com/a/8907356
//
template <typename T>
class mkvec {
public:
    typedef mkvec<T> my_type;
    my_type& operator<< (const T& val) {
        data_.push_back(val);
        return *this;
    }
    my_type& operator<< (const std::vector<T>& inVector) {
        this->data_.reserve(this->data_.size() + inVector.size());
        this->data_.insert(this->data_.end(), inVector.begin(), inVector.end());
        return *this;
    }
    operator std::vector<T>() const {
        return data_;
    }
private:
    std::vector<T> data_;
};

std::vector<int32_t>    vec1;
std::vector<int32_t>    vec2;

vec1 = mkvec<int32_t>() << 5 << 8 << 19 << 79;  
// vec1 = (5,8,19,79)
vec2 = mkvec<int32_t>() << 1 << 2 << 3 << vec1 << 10 << 11 << 12;  
// vec2 = (1,2,3,5,8,19,79,10,11,12)

7

Các phương thức dưới đây có thể được sử dụng để khởi tạo vector trong c ++.

  1. int arr[] = {1, 3, 5, 6}; vector<int> v(arr, arr + sizeof(arr)/sizeof(arr[0]));

  2. vector<int>v; v.push_back(1); v.push_back(2); v.push_back(3); và như thế

  3. vector<int>v = {1, 3, 5, 7};

Cái thứ ba chỉ được phép trong C ++ 11 trở đi.


5

Có rất nhiều câu trả lời hay ở đây, nhưng vì tôi đã tự mình đến trước khi đọc nó, tôi nghĩ rằng dù sao tôi cũng sẽ ném nó lên đây ...

Đây là một phương pháp mà tôi đang sử dụng cho phương pháp này sẽ hoạt động phổ biến trên các trình biên dịch và nền tảng:

Tạo một cấu trúc hoặc lớp như một thùng chứa cho bộ sưu tập các đối tượng của bạn. Xác định hàm quá tải toán tử cho <<.

class MyObject;

struct MyObjectList
{
    std::list<MyObject> objects;
    MyObjectList& operator<<( const MyObject o )
    { 
        objects.push_back( o );
        return *this; 
    }
};

Bạn có thể tạo các hàm lấy cấu trúc của bạn làm tham số, ví dụ:

someFunc( MyObjectList &objects );

Sau đó, bạn có thể gọi hàm đó, như thế này:

someFunc( MyObjectList() << MyObject(1) <<  MyObject(2) <<  MyObject(3) );

Bằng cách đó, bạn có thể xây dựng và chuyển một bộ sưu tập các đối tượng có kích thước động đến một hàm trong một dòng sạch duy nhất!


4

Nếu bạn muốn một cái gì đó theo cùng thứ tự chung như Boost :: gán mà không tạo ra sự phụ thuộc vào Boost, thì sau đây ít nhất là tương tự mơ hồ:

template<class T>
class make_vector {
    std::vector<T> data;
public:
    make_vector(T const &val) { 
        data.push_back(val);
    }

    make_vector<T> &operator,(T const &t) {
        data.push_back(t);
        return *this;
    }

    operator std::vector<T>() { return data; }
};

template<class T> 
make_vector<T> makeVect(T const &t) { 
    return make_vector<T>(t);
}

Mặc dù tôi muốn cú pháp sử dụng nó sạch hơn, nhưng nó vẫn không đặc biệt khủng khiếp:

std::vector<int> x = (makeVect(1), 2, 3, 4);

4
typedef std::vector<int> arr;

arr a {10, 20, 30};       // This would be how you initialize while defining

Để biên dịch sử dụng:

clang++ -std=c++11 -stdlib=libc++  <filename.cpp>

Câu hỏi nêu rõ C ++ 03 (không phải 11)
Mike P

1
Tôi nghĩ rằng nó đã không chỉ định 03 khi tôi trả lời này. Đừng nhớ hoàn hảo mặc dù. Tuy nhiên, nó vẫn là một câu trả lời hữu ích cho ai đó đang tìm kiếm một giải pháp nhanh chóng.
shaveenk

4
// Before C++11
// I used following methods:

// 1.
int A[] = {10, 20, 30};                              // original array A

unsigned sizeOfA = sizeof(A)/sizeof(A[0]);           // calculate the number of elements

                                                     // declare vector vArrayA,
std::vector<int> vArrayA(sizeOfA);                   // make room for all
                                                     // array A integers
                                                     // and initialize them to 0 

for(unsigned i=0; i<sizeOfA; i++)
    vArrayA[i] = A[i];                               // initialize vector vArrayA


//2.
int B[] = {40, 50, 60, 70};                          // original array B

std::vector<int> vArrayB;                            // declare vector vArrayB
for (unsigned i=0; i<sizeof(B)/sizeof(B[0]); i++)
    vArrayB.push_back(B[i]);                         // initialize vArrayB

//3.
int C[] = {1, 2, 3, 4};                              // original array C

std::vector<int> vArrayC;                            // create an empty vector vArrayC
vArrayC.resize(sizeof(C)/sizeof(C[0]));              // enlarging the number of 
                                                     // contained elements
for (unsigned i=0; i<sizeof(C)/sizeof(C[0]); i++)
     vArrayC.at(i) = C[i];                           // initialize vArrayC


// A Note:
// Above methods will work well for complex arrays
// with structures as its elements.

4

Nếu mảng là:

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 

4

Nó khá thuận tiện để tạo một vectơ nội tuyến mà không xác định biến khi viết bài kiểm tra, ví dụ:

assert(MyFunction() == std::vector<int>{1, 3, 4}); // <- this.

3

Liên quan, bạn có thể sử dụng các mục sau nếu bạn muốn có một vectơ hoàn toàn sẵn sàng để đi vào một câu lệnh nhanh (ví dụ: ngay lập tức chuyển sang hàm khác):

#define VECTOR(first,...) \
   ([](){ \
   static const decltype(first) arr[] = { first,__VA_ARGS__ }; \
   std::vector<decltype(first)> ret(arr, arr + sizeof(arr) / sizeof(*arr)); \
   return ret;})()

chức năng ví dụ

template<typename T>
void test(std::vector<T>& values)
{
    for(T value : values)
        std::cout<<value<<std::endl;
}

sử dụng ví dụ

test(VECTOR(1.2f,2,3,4,5,6));

mặc dù hãy cẩn thận về số thập phân, đảm bảo giá trị đầu tiên rõ ràng là những gì bạn muốn.


3

Có nhiều cách khác nhau để mã hóa một vectơ, tôi sẽ chia sẻ một vài cách:

  1. Khởi tạo bằng cách đẩy từng giá trị một
// Create an empty vector 
    vector<int> vect;  

    vect.push_back(10); 
    vect.push_back(20); 
    vect.push_back(30); 
  1. Khởi tạo như mảng
vector<int> vect{ 10, 20, 30 };
  1. Đang khởi tạo từ một mảng
    int arr[] = { 10, 20, 30 }; 
    int n = sizeof(arr) / sizeof(arr[0]); 

    vector<int> vect(arr, arr + n); 
  1. Bắt đầu từ một vector khác
    vector<int> vect1{ 10, 20, 30 }; 

    vector<int> vect2(vect1.begin(), vect1.end()); 

2

"Làm cách nào để tạo một vectơ STL và khởi tạo nó như trên? Cách tốt nhất để làm điều đó với nỗ lực gõ tối thiểu là gì?"

Cách dễ nhất để khởi tạo một vectơ khi bạn khởi tạo mảng dựng sẵn của mình là sử dụng danh sách trình khởi tạo được giới thiệu trong C ++ 11 .

// Initializing a vector that holds 2 elements of type int.
Initializing:
std::vector<int> ivec = {10, 20};


// The push_back function is more of a form of assignment with the exception of course
//that it doesn't obliterate the value of the object it's being called on.
Assigning
ivec.push_back(30);

ivec có 3 phần tử kích thước sau khi Assigning (câu lệnh được gắn nhãn) được thực thi.


Trong các dòng tương tự, tôi đang cố gắng khởi tạo bản đồ, std :: map <int, bool> catinfo = {{1, false}}; Nhưng sau đó nhận được lỗi lỗi này: trong C ++ 98 'catinfo' phải được khởi tạo bởi nhà xây dựng, không phải bởi '{...}'
pdk

2

B. Stroustrup mô tả một cách hay để vận hành chuỗi trong 16.2.10 Selfreference trên trang 464 trong phiên bản C ++ 11 của Prog. Lang. trong đó một hàm trả về một tham chiếu, ở đây được sửa đổi thành một vectơ. Bằng cách này bạn có thể xâu chuỗi như thế v.pb(1).pb(2).pb(3);nhưng có thể là quá nhiều công việc cho những lợi ích nhỏ như vậy.

#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


Thư viện armadillo thực hiện việc này để khởi tạo ma trận nhưng sử dụng toán tử << thay vì hàm được đặt tên: arma.sourceforge.net/docs.html#element_initialisation
Agnel Kurian

0

Cách đơn giản nhất, tiện dụng hơn (với C ++ 11 trở lên):

auto my_ints = {1,2,3};

0

Trong trường hợp bạn muốn có nó trong lớp của riêng bạn:

#include <initializer_list>
Vector<Type>::Vector(std::initializer_list<Type> init_list) : _size(init_list.size()),
_capacity(_size),
_data(new Type[_size])
{
    int idx = 0;
    for (auto it = init_list.begin(); it != init_list.end(); ++it)
        _data[idx++] = *it;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.