Cách đơn giản nhất để chuyển mảng thành vectơ là gì?


94

Cách đơn giản nhất để chuyển mảng thành vectơ là gì?

void test(vector<int> _array)
{
  ...
}

int x[3]={1, 2, 3};
test(x); // Syntax error.

Tôi muốn chuyển đổi x từ mảng int sang vector theo cách đơn giản nhất.

Câu trả lời:


140

Sử dụng hàm vectortạo có hai trình vòng lặp, lưu ý rằng con trỏ là trình vòng lặp hợp lệ và sử dụng chuyển đổi ngầm định từ mảng thành con trỏ:

int x[3] = {1, 2, 3};
std::vector<int> v(x, x + sizeof x / sizeof x[0]);
test(v);

hoặc là

test(std::vector<int>(x, x + sizeof x / sizeof x[0]));

nơi sizeof x / sizeof x[0]rõ ràng là 3trong bối cảnh này; đó là cách chung để lấy số phần tử trong một mảng. Lưu ý rằng x + sizeof x / sizeof x[0]chỉ một phần tử ngoài phần tử cuối cùng.


1
Bạn có thể giải thích nó không? Tôi đã đọc vector<int> a(5,10);nghĩa là make room for 5 int` và khởi tạo chúng bằng 10. Nhưng x, x + ... của bạn hoạt động như thế nào? bạn có thể giải thích?
Asif Mushtaq

1
@UnKnown thay vì chọn vector<int>::vector(size_type, int), nó chọn vector<int>::vector(int*, int*), sao chép phạm vi được biểu thị bằng cặp con trỏ đó. Đầu tiên là tình trạng quá tải (2), thứ hai là tình trạng quá tải (4) ở đây
Caleth

1
Trên c ++ 11 std :: scope tốt hơn phương thức sizeof. sizeof x / sizeof x[0] == std::extent<decltype(x)>::value
Isaac Pascual

116

Cá nhân tôi khá thích cách tiếp cận C ++ 2011 vì nó không yêu cầu bạn sử dụng sizeof()cũng như không nhớ điều chỉnh giới hạn mảng nếu bạn thay đổi giới hạn mảng (và bạn cũng có thể xác định hàm liên quan trong C ++ 2003 nếu bạn muốn ):

#include <iterator>
#include <vector>
int x[] = { 1, 2, 3, 4, 5 };
std::vector<int> v(std::begin(x), std::end(x));

Rõ ràng, với C ++ 2011, bạn vẫn có thể muốn sử dụng danh sách trình khởi tạo:

std::vector<int> v({ 1, 2, 3, 4, 5 });

2
nó sao chép mảng hay nó chỉ trỏ tới nó? Tôi đang lo ngại với hiệu suất
kirill_igum

2
std::vector<T>luôn sở hữu các Tđối tượng. Điều này có hai ý nghĩa: khi chèn đối tượng vào một vectơ, chúng được sao chép và chúng được sắp xếp trong bộ nhớ. Đối với các đối tượng nhỏ hợp lý, ví dụ chuỗi các chuỗi ngắn, sắp xếp là một hiệu suất chính. Nếu các đối tượng của bạn lớn và tốn kém để sao chép, bạn có thể muốn lưu trữ các con trỏ [bằng cách nào đó được quản lý tài nguyên] đến các đối tượng. Cách tiếp cận nào hiệu quả hơn tùy thuộc vào đối tượng mà bạn có sự lựa chọn.
Dietmar Kühl

vì vậy nếu tôi muốn giao diện một thư viện c ++ và ac và sao chép từ c-array sang vector và ngược lại, không có cách nào để trả tiền phạt của 2 bản sao? (Tôi đang sử dụng thư viện eigen và GSL)
kirill_igum

16

Con trỏ có thể được sử dụng giống như bất kỳ trình vòng lặp nào khác:

int x[3] = {1, 2, 3};
std::vector<int> v(x, x + 3);
test(v)

2
Trong cuộc sống thực, bạn có thể muốn trừu tượng hóa kích thước mảng, ví dụ: sử dụng const size_t X_SIZE = 3;để biểu thị kích thước mảng hoặc tính toán nó từ sizeof. Tôi đã bỏ qua phần đó để dễ đọc.
Rafał Rawicki

11

Bạn đang đặt câu hỏi sai ở đây - thay vì buộc mọi thứ vào một vectơ, hãy hỏi cách bạn có thể chuyển đổi thử nghiệm thành hoạt động với các trình vòng lặp thay vì một vùng chứa cụ thể. Bạn cũng có thể cung cấp quá tải để duy trì khả năng tương thích (và xử lý miễn phí các vùng chứa khác cùng lúc):

void test(const std::vector<int>& in) {
  // Iterate over vector and do whatever
}

trở thành:

template <typename Iterator>
void test(Iterator begin, const Iterator end) {
    // Iterate over range and do whatever
}

template <typename Container>
void test(const Container& in) {
    test(std::begin(in), std::end(in));
}

Điều này cho phép bạn làm:

int x[3]={1, 2, 3};
test(x); // Now correct

( Bản demo Ideone )


"thay vì buộc mọi thứ vào một vectơ, hãy hỏi cách bạn có thể chuyển đổi thử nghiệm thành hoạt động với các trình vòng lặp thay vì một vùng chứa cụ thể." Tại sao điều này tốt hơn?
aquirdturtle

1
@aquirdturtle bởi vì bây giờ, thay vì chỉ hỗ trợ vectơ, bạn hỗ trợ danh sách và mảng, đồng thời tăng cường vùng chứa và biến đổi các trình vòng lặp và phạm vi và ....
Flexo

2
và bạn không cần sao chép dữ liệu
Lightness Races trong Orbit.

2

Một cách đơn giản có thể là sử dụng assign()hàm được định nghĩa trước trong vectorlớp.

ví dụ

array[5]={1,2,3,4,5};

vector<int> v;
v.assign(array, array+5); // 5 is size of array.

2
Tương đương với việc sử dụng ctor, đã được đề cập trong các câu trả lời hiện có cách đây khoảng bảy năm. Thêm không có gì ...
Lightness Races ở Orbit
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.