Size-Of C-Array as a function? [duplicate]
Possible Duplicate:
How does this “size of array” template function work?
Is there any possibility to implement NARR
without a macro in C++ (C++0x)?
const static pair<string,int> data[] = {
{"Montag",1}, {"Dienstag",2}, {"Mittwoch",3}, {"Donnerstag",4},
{"Freitag",5}, {"Samstag",6}, {"Sonntag",7}
};
#define NARR(A) (sizeof(A)/sizeof(*A))
const static map<string,int> german_weekdays(data, data+NARR(data));
A simple function is not possible, because then the []
loses its size-information and becomes just another poine开发者_JS百科r:
size_t narr(sometype arr[]) { /* won't work */ }
Templates? Overloading? Magic?
It is possible in C++:
template< typename T, std::size_t Size >
std::size_t size(const T (&)[Size])
{
return Size;
}
The advantage of this over the macro solution is that the compiler will cough up a nasty error message if you try to pass a pointer to this.
In C++0x:
#include <iterator>
const static map<string,int> german_weekdays(data, std::end(data));
Also you can use std::begin(data)
if you like, for symmetry or genericness[*]. And possibly you can use an initializer list instead of an array anyway...
[*] Although for full genericness, you should probably do:
using std::begin;
using std::end;
begin(data), end(data);
The reason is that the new "range-based for loop" syntax is equivalent to using begin
and end
without qualification, but with std
as an associated namespace for ADL. So as with std::swap
, authors of types might provide begin
and end
functions that are intended to be found via ADL. They probably ought to provide begin()
and end()
member functions instead, which std::begin
and std::end
will call. But if they provide something that works with ranged-based for, and doesn't work with your code, then you'll have to have an argument who should change.
I can't test this right now, because I've been away for a while and the latest GCC 4.6 just refused to compile, but constexpr
should make short work of the question. Of course, it's better to sidestep this issue using Steve's suggestion.
template< typename T, size_t N >
constexpr size_t narr( T const (&)[ N ] )
{ return N; }
精彩评论