5 ms·
In C++, you can do this by passing the array by reference: void foo(int (&foo)[10]) {} However, that is not "minimum of 10" but "exactly 10". You can als
by matthavener 14y ago
In C++, you can do this by passing the array by reference:
void foo(int (&foo)[10]) {}
However, that is not "minimum of 10" but "exactly 10".
You can also get the size at compile time:
template <size_t N> void foo(int (&foo)[N]) { int newarry[N+2]; }
I've used the above for something like this:
template <size_t N> void safe_strcpy(char (&buf)[N], const char *src) {
strncpy(buf, src, N-1);
buf[N-1] = 0;
}
- pyrtsa 14y agoAnd, by extending your second example, we can enforce the minimum array size with std::enable_if (C++11; boost::enable_if_c with C++03): template <size_t N> typename enable_if<(N >= 10), void>::type foo(int (&bar)[N]) { ... } EDIT: Changed condition from N >= 0 into a more meaningful one. X-)
- pbsd 14y agoThe more readable C++11 version would use static_assert: template <size_t N> foo(int (&bar)[N]) { static_assert(N >= 10, "Array needs >= 10 elements!"); ... }
- pyrtsa 14y agoCorrect. The key difference is that the enable_if version can be overloaded with mutually exclusive requirements: template <size_t N> typename enable_if<(1 < N && N < 10), void>::type foo(int (&bar)[N]) { // called when 1 < N && N < 10 } template <size_t N> typename enable_if<(N >= 10), void>::type foo(int (&bar)[N]) { // called when N >= 10 } OTOH, the key advantage in static_assert is the meaningful error message.
- abcd_f 14y agoThis will generate separate function bodies for different values of N.
- zokier 14y agoI don't think that is more readable. With enable_if the precondition is clearly visible at the function header, while the static_assert is inside the body and thus more easily accidentally ignored.
- obiterdictum 14y agoOn the other hand, static_assert will have a more helpful compile error for users of the code. They will clearly see assertion condition that failed, rather than missing candidate error due to substitution failure (or worse, a different overload silently considered instead).
- huhtenberg 14y ago... and just as I was going to make a smart-ass joke about Boost probably having another contrived contraption just for that - there it is, already sneaked into the standard too.
- chc 14y agoThis works with pointers in both C and C++. int (*foo)[10] is a pointer to an array of exactly 10 elements. The novel thing being pointed out in the OP is the "10 or more" aspect.
- cliffbean 14y agoThat's true, until you forget and type foo[i] instead of (* foo)[i]. Of course, compilers will usually catch that mistake at compile time... There'a an interesting analogy with structs here. K&R invented the -> operator specifically to obviate (* ptr).member. It's too bad that arrays took a different route through C's history and didn't manage to end up in a place where a similar convenience would make sense.