2010-01-29 33 views
8

Có cách nào để hạn chế kích thước của mảng khi được chuyển làm đối số cho hàm không?Hạn chế kích thước của một mảng khi được chuyển đến một hàm

Ý tôi là một cái gì đó như thế này có thể?

/*following will lead to compile time error */ 

template<typename T, size_t n>=20> // or template<typename T,size_t n<=20> 
void func(T (&a)[n]) 
{ 
    // do something with a 

} 

Tôi muốn kích thước của mảng tối thiểu là (hoặc nhiều nhất) n (n có thể có bất kỳ giá trị nào).

Ví dụ:

Khi n=20 tôi phải vượt qua một mảng với ít nhất (hoặc ít nhất) 20 yếu tố. Có cách nào trong C + + cho điều này?

+1

Bạn muốn hành vi nào nếu mảng không đúng kích thước? –

+1

@Neil: Lỗi biên dịch. –

Trả lời

15

Bạn chỉ có thể yêu cầu xác nhận tĩnh - ví dụ: với Tăng tĩnh khẳng định:

template<typename T, size_t n> 
void func(T (&a)[n]) { 
    BOOST_STATIC_ASSERT(n >= 20); 
    // ... 
} 

Một thực hiện tùy chỉnh cơ bản (không giải quyết vấn đề của việc sử dụng nó sau đó thêm một lần mỗi phạm vi) có thể trông giống như sau:

template<bool b> struct StaticAssert; 
template<> struct StaticAssert<true> {}; 
#define STATIC_ASSERT(x) StaticAssert<(x)> static_asserter 

Nếu bạn muốn hành vi khác nhau nếu yêu cầu được đáp ứng, hãy sử dụng một cái gì đó như enable_if hoặc chuyên môn dựa trên thẻ. Ví dụ sử dụng enable_if:

template<class T, size_t n> 
typename boost::enable_if<(n >= 20), void>::type 
func(T (&a)[n]) { /* ... */ } 

template<class T, size_t n> 
typename boost::disable_if<(n >= 20), void>::type 
func(T (&a)[n]) { /* ... */ } 
+2

Lưu ý: Việc biết kích thước không ngăn cản bạn truy cập vượt quá kết thúc (tức là trình biên dịch sẽ không kiểm tra chỉ mục mảng của bạn). –

+0

+ 1 rất intersting: không biết về macro này, cho phép nhận được một lỗi thời gian biên dịch. – sergiom

+0

cơ chế mẫu C++ đá ass! nếu bạn tìm thấy điều này thú vị có được những cuốn sách từ câu trả lời của tôi. : D –

-2

Bạn đang cố gắng sử dụng các mẫu (thời gian biên dịch) để biết có bao nhiêu mặt hàng sẽ được trong mảng của bạn khi chạy. Nó không thể làm như bạn cố gắng làm điều đó.

Bạn sẽ phải dựa vào mã bên ngoài chức năng của bạn hoặc bên trong hàm

+2

ofcourse nó là, cơ chế mẫu trong C + + là turing hoàn thành. –

+0

Mảng theo nghĩa hẹp có kích thước cố định tại thời điểm biên dịch. – visitor

-3

Không có như vậy một cấu trúc trong C++, cho phép bạn nhận được một lỗi thời gian biên dịch. Nhưng tôi nghĩ rằng bằng cách sử dụng các mẫu bạn có thể thực hiện một khung có chứa một cái gì đó giống như một lớp LimitedArray được sử dụng thay vì một loại mảng cơ bản.

5

Câu trả lời của GF là chính xác, nếu bạn muốn nhiều tính năng hoặc quyết định hơn tại thời điểm biên dịch, bạn có thể muốn xem boost::mpl. C++ Template Metaprogramming vạch ra những gì có thể với boost :: MPL và cách nó được thiết kế. Modern C++ design, không liên quan đến MPL, đi vào các kỹ thuật thiết kế để tận dụng tính đa hình thời gian biên dịch

+0

Tôi nghĩ rằng người ta không cần phải làm theo các liên kết để xem những cuốn sách đề cập đến, chỉ cần thay đổi nó nếu nó không phù hợp với bạn. –

+0

cảm ơn gf, tôi đã lười biếng: P –

3

Câu trả lời của GF khá thú vị, nhưng Boost.Array không thể không đề cập đến.

template< typename T > 
void func(boost::array< T, 20 > &a) { 

Với câu hỏi của bạn và trả lời GF, nó trông giống như một chuyển đổi ngầm tính toán miễn phí, loại- và phạm vi an toàn từ T(&)[20] để some_array_template<T,20> sẽ là ngữ nghĩa có thể, nhưng boost::array không cho phép điều đó. Tuy nhiên, bạn có thể xem xét di chuyển hoàn toàn sang boost::array nếu bạn có nhiều logic tương tự. Và nó đủ đơn giản để sử dụng làm cơ sở để cuộn của riêng bạn, nếu bạn muốn chuyển đổi ngầm định.

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