2014-07-25 18 views
5

Tôi đang cố gắng để khởi tạo đối tượng thuộc loại điều:Làm cách nào để khởi tạo đối tượng std :: array <std :: array <T, 2>, 2>?

template<typename T> 
    struct thing : std::array<std::array<T, 2>, 2> 
    { 
    }; 

thing<int> t1 {{ {1,2}, {3,4} }}; 

tôi nhận được:

error: no matching function for call to ‘thing<int>::thing(<brace-enclosed initializer list>)’ 
thing<int> t1 {{{1,2},{3,4}}}; 

Ditto với

thing<int> t0{{ 1, 2, 3, 4 }}; 

và một số thứ khác.

+3

tại sao bạn buộc phải kế thừa từ một mảng 2D? – rashmatash

+2

Nếu bạn đang cố gắng để bí danh mảng, bạn nên làm 'mẫu sử dụng điều = std :: mảng , 2>;' – Quentin

Trả lời

9

Nếu bạn đang sử dụng trình biên dịch C++ 17, bạn chỉ thiếu một bộ dấu ngoặc bổ sung. Sau đây compiles:

thing<int> t1 { { { {1,2}, {3,4} } } }; 
//   | | | |- braces for inner array 
//   | | |--- braces for outer array 
//   | |----- braces for base sub object of thing 
//   |------- braces for list initialization of thing 

C++ 17 modified các quy tắc để làm cốt để cho phép các lớp cơ sở, miễn là họ đang public và phi virtual.

Từ §11.6.1/1 [dcl.init.aggr]

Một tổng là một mảng hoặc một lớp học với
(1.1) không constructors dùng cung cấp, explicit, hoặc được thừa kế ([class.ctor]),
(1.2) không có thành viên dữ liệu riêng tư hoặc không được bảo vệ ([class.access]),
(1.3) không có chức năng ảo và
(1.4) không có lớp cơ sở ảo, riêng tư hoặc được bảo vệ ([class.mi]).

Các lớp cơ sở hiện nay được coi là elements of the aggregate, và bản thân họ có thể được khởi tạo sử dụng list-khởi.

Các yếu tố của một tổng hợp bao gồm:
(2.1) cho một mảng, các phần tử mảng thứ tự tăng dần số phụ, hoặc
(2.2) cho một lớp học, các lớp cơ sở trực tiếp trong việc kê khai thứ tự, tiếp theo là các thành viên dữ liệu không tĩnh trực tiếp ([class.mem]) không phải là thành viên của một liên minh ẩn danh, theo thứ tự khai báo.


C++ 14, và trước đó, phiên bản của câu trả lời sau:

std::array là một tổng hợp, và khởi tạo được thực hiện bằng cách sử dụng chuẩn bị tinh thần-init-list là tổng hợp khởi tạo. Tuy nhiên, thing không phải là tổng hợp vì nó có một lớp cơ sở.

Từ §8.5.1/1 [dcl.init.aggr]

Một tổng là một mảng hoặc một lớp học (khoản 9) không có nhà xây dựng người dùng cung cấp (12.1), không có các thành viên dữ liệu cá nhân hoặc bảo vệ không tĩnh (khoản 11), không có căn cứ các lớp (Điều 10) và không có chức năng ảo (10.3).

Do đó, việc khởi tạo tổng hợp sẽ không hoạt động. Tùy thuộc vào những gì bạn đang cố gắng để làm, bạn có muốn cung cấp một constructor cho thing rằng có một đối std::array<std::array<T, 2>, 2>, và khởi tạo cơ sở subobject

template<typename T> 
struct thing : std::array<std::array<T, 2>, 2> 
{ 
    thing(std::array<std::array<T, 2>, 2> arr) 
    : std::array<std::array<T, 2>, 2>(arr) 
    {} 
}; 
thing<int> t{ {{ {{1,2}}, {{3,4}} }} }; 

Hoặc có thing chứa std::array như một thành viên dữ liệu. Bây giờ thing vẫn là tổng hợp.

template<typename T> 
struct thing 
{ 
    std::array<std::array<T, 2>, 2> arr; 
}; 
thing<int> t{ {{ {{1,2}}, {{3,4}} }} }; 

Nếu bạn đang cố gắng làm là có thing là một bí danh cho một array<array<T,2>,2>, sau đó bạn không cần một trong hai bên trên. Sử dụng

template<typename T> 
using thing = std::array<std::array<T, 2>, 2>; 

thing<int> t{{ {{1,2}}, {{3,4}} }}; 
Các vấn đề liên quan