2016-12-27 19 views
47

Với struct này:Nhận kích thước của std :: mảng mà không cần một thể hiện

struct Foo { 
    std::array<int, 8> bar; 
}; 

Làm thế nào tôi có thể nhận được số phần tử của mảng bar nếu tôi không có một thể hiện của Foo?

+2

cách sử dụng macro thay vì mã hóa cứng kích thước mảng? –

+0

'sizeof (Foo :: bar);'? – max66

+14

@ WebertS.Lima - Làm hư hỏng ý nghĩ. Không phải là macro. – StoryTeller

Trả lời

76

Bạn có thể sử dụng std::tuple_size:

std::tuple_size<decltype(Foo::bar)>::value 
+13

Hooking điều này ở đây: các lớp khác nhau và chức năng đối phó với 'std :: tuple's (' std :: tuple_size', 'std :: tuple_element',' std :: get') có chuyên môn tiện dụng để xử lý một 'std: : mảng 'như' std :: tuple '. – Quentin

-4

Bạn có thể sử dụng như:

sizeof Foo().bar 
+3

Xem [nhận xét này từ OP] (http://stackoverflow.com/questions/41345182/get-size-of-stdarray-without-an-instance#comment69892397_41345182): anh ấy theo số lượng phần tử chứ không phải tổng kích thước. – Quentin

+0

@Happy - OP sửa đổi câu trả lời: anh ta muốn số phần tử trong mảng (8 trong ví dụ), không phải là chú thích 'sizeof' – max66

+3

: sẽ không hoạt động đối với các lớp không có hàm tạo mặc định –

4

Bạn có thể làm điều đó giống như đối với mảng di sản:

sizeof(Foo::bar)/sizeof(Foo::bar[0]) 
+2

hoặc sử dụng ['std :: extent'] dễ đọc hơn nhiều (http://en.cppreference.com/w/cpp/types/extent) nhưng đây không phải là câu trả lời vì điều này vẫn sẽ yêu cầu xây dựng một cá thể. – Mgetz

+3

Một vài điều khác cần lưu ý 'sizeof std :: array ' có thể không bằng 'sizeof int [4]' là một chi tiết thực hiện. Hơn nữa, nếu bạn định xây dựng ['std :: array'] (http://en.cppreference.com/w/cpp/container/array) thì chỉ cần sử dụng [' size() '] (http: //en.cppreference.com/w/cpp/container/array/size) thành viên – Mgetz

+2

Tôi có nghĩa là 'sizeof (Foo :: bar)/sizeof (Foo :: bar [0])'. Không có trường hợp nào của Foo cần thiết. – Waxrat

1

Sử dụng:

sizeof(Foo::bar)/sizeof(int) 
+0

Tôi đã thử và tôi nhận được cùng một giá trị cho cả hai. '#include #include sử dụng không gian tên std; struct Foo { std :: mảng thanh; }; int main() { cout << sizeof (Foo :: bar)/sizeof (int) << endl; cout << std :: tuple_size :: giá trị << endl; trả lại 0; } ' –

24

Mặc dù số good answer của @ Jarod42, đây là một giải pháp có thể khác dựa trên decltype không sử dụng tuple_size.
Nó sau một tối thiểu, làm việc ví dụ mà các công trình trong C++ 11:

#include<array> 

struct Foo { 
    std::array<int, 8> bar; 
}; 

int main() { 
    constexpr std::size_t N = decltype(Foo::bar){}.size(); 
    static_assert(N == 8, "!"); 
} 

std::array đã có một hàm thành viên constexpr tên size trả về giá trị mà bạn đang tìm kiếm.

+2

vì vậy điều này có cùng một vấn đề như câu trả lời của @ waxrat dưới đây, nó yêu cầu xây dựng ngay cả khi xây dựng ** có thể ** là' constexpr', theo nghĩa đó 'std :: tuple_size' là một câu trả lời tốt hơn vì nó doesn ' t yêu cầu bất kỳ xây dựng hoặc phá hủy trong trường hợp không 'constexpr'. – Mgetz

+3

@Mgetz Tôi không nói nó tốt hơn. :-) ... Các giải pháp và câu trả lời khác nhau có thể giúp người đọc trong tương lai, cho dù họ có được chấp nhận hay không. – skypjack

+0

do đó nhận xét của tôi, tôi đã tìm cách để đảm bảo độc giả như vậy sẽ hiểu tại sao 'std :: tuple_size' là một lựa chọn tốt hơn. Điều đó nói rằng tôi có thể làm một 'bằng cách sử dụng array_size = std :: tuple_size' cho dễ đọc. – Mgetz

7

Bạn có thể cung cấp Foo thành viên public static constexpr.

struct Foo { 
static constexpr std::size_t bar_size = 8; 
std::array<int, bar_size> bar; 
} 

Bây giờ bạn biết kích thước của thanh từ Foo::bar_size và bạn có thể linh động gia tăng của việc đặt tên bar_size một cái gì đó mô tả nhiều hơn nếu Foo bao giờ có nhiều mảng có cùng kích thước.

+0

Với các câu trả lời khác cho thấy điều này có thể thực hiện mà không có 'const tĩnh', tôi không tìm thấy câu trả lời hay này. – Tas

+0

@Tas: Theo tôi, vấn đề là câu trả lời này được trả về: thay vì trả lời câu hỏi về cách lấy một số phần tử của mảng hiện có, nó nói để khai báo một số đã biết và thay đổi khai báo của mảng thành mẫu nó cái đó. Vì vậy, thành viên 'static constexpr' thực sự không phải là điều đáng phàn nàn; nó sẽ tiêu thụ không có không gian trong các trường hợp và được hoàn toàn tối ưu hóa trong đơn vị dịch thuật của nó (trừ khi địa chỉ của nó được thực hiện, nhưng sau đó sẽ yêu cầu một định nghĩa out-of-line, do đó). –

+0

@Tas @underscore_d Cảm ơn. Lý do tôi đưa ra câu trả lời này là vì câu trả lời có điểm cao là phức tạp. Kích thước của thanh không có 'constexpr' tĩnh là một số ma thuật. Giải pháp này loại bỏ số ma thuật và giải quyết vấn đề bằng một dòng đơn giản. –

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