2011-11-19 34 views
46

Trừ khi tôi nhầm lẫn, chúng ta có thể để tạo ra một std: mảng trong các cách sau:Sử dụng std :: mảng với khởi liệt kê

std::array<std::string, 2> strings = { "a", "b" }; 
std::array<std::string, 2> strings({ "a", "b" }); 

Tuy nhiên, sử dụng GCC 4.6.1 Tôi không thể có được bất kỳ cái nào trong số này đều hoạt động. Trình biên dịch chỉ cần nói:

expected primary-expression before ',' token 

và danh sách khởi tạo vẫn hoạt động tốt với std :: vector. Vì vậy, đó là nó? Tôi có nhầm lẫn với suy nghĩ std :: mảng nên chấp nhận danh sách khởi tạo, hoặc có nhóm GNU C++ tiêu chuẩn thư viện goofed?

+0

Đó là clang bị rơi ... – Dani

+0

Tôi không chắc liệu điều này có hoạt động hay không (nhưng tôi không cập nhật thông tin 0x) nhưng lỗi hay không, tôi nghĩ đó là vì bạn đang sử dụng 'std: : chuỗi' với chuỗi ký tự. Bạn đã thử gói các chuỗi ký tự bằng 'std :: string()' chưa? –

+0

@Chris: Tính năng này phù hợp với tôi với gcc 4.6.1 trên Mac OSX 10.6. Bạn đang sử dụng các tùy chọn trình biên dịch nào? – juanchopanza

Trả lời

72

std::array thật thú vị. Nó được định nghĩa cơ bản như sau:

template<typename T, int size> 
struct std::array 
{ 
    T a[size]; 
}; 

Đây là cấu trúc chứa mảng. Nó không có một hàm tạo có danh sách khởi tạo. Nhưng std::array là một tổng hợp theo các quy tắc của C++ 11, và do đó nó có thể được tạo ra bằng cách tổng hợp khởi tạo. Để tổng hợp khởi tạo mảng bên các cấu trúc, bạn cần một bộ thứ hai của dấu ngoặc nhọn:

std::array<std::string, 2> strings = {{ "a", "b" }}; 

Lưu ý rằng tiêu chuẩn không cho thấy dấu ngoặc thêm có thể được elided trong trường hợp này. Vì vậy, nó có khả năng là một lỗi GCC.

+0

Ủy ban tiêu chuẩn có thực hiện điều này không? – Dani

+0

Tại sao tiêu chuẩn chỉ yêu cầu 'std :: array' có một hàm tạo làm việc với các danh sách khởi tạo? –

+6

@PaulManta: Bởi vì sau đó nó sẽ không đủ điều kiện để khởi tạo tổng hợp. Tổng hợp khởi tạo có thể được xếp trong thời gian biên dịch, tùy thuộc vào loại phần tử mảng (std :: string không đủ điều kiện). Khởi tạo danh sách khởi tạo * phải * là cuộc gọi hàm thời gian chạy, bất kể loại phần tử mảng nào. –

9

Để thêm vào các câu trả lời được chấp nhận:

std::array<char, 2> a1{'a', 'b'}; 
std::array<char, 2> a2 = {'a', 'b'}; 
std::array<char, 2> a3{{'a', 'b'}}; 
std::array<char, 2> a4 = {{'a', 'b'}}; 

tất cả công việc trên GCC 4.6.3 (Xubuntu 12.01). Tuy nhiên,

void f(std::array<char, 2> a) 
{ 
} 

//f({'a', 'b'}); //doesn't compile 
f({{'a', 'b'}}); 

ở trên yêu cầu đôi dấu ngoặc đơn để biên dịch. Phiên bản với niềng răng đơn kết quả trong các lỗi sau:

../src/main.cc: In function ‘int main(int, char**)’: 
../src/main.cc:23:17: error: could not convert ‘{'a', 'b'}’ from ‘<brace-enclosed initializer list>’ to ‘std::array<char, 2ul>’ 

Tôi không chắc chắn những gì khía cạnh suy luận kiểu/chuyển đổi làm cho mọi thứ làm việc theo cách này, hoặc nếu điều này là một điều không minh bạch thực hiện của GCC.

Các vấn đề liên quan