By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,116 Members | 1,282 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,116 IT Pros & Developers. It's quick & easy.

Array size Template and references to array

P: n/a
Hi all,
I was just browsing the archives when I saw one fo the messages posted
recently about array size template et al.

All along, I have been using the usual template to get the size of the
array.
template<typename T, std::size_t N>
std::size_t size_of(T(&)[N])
{
return N;
}

But as one person pointed out, the following definition fails with the
above template, which is what I have always noticed when I use similar
definitions.
int x[5];
int y[size_of(x)]; //fails here

I always went back to the simple way in these definition
int y[sizeof(x)/sizeof(*x)]; //the simple way.

The person who pointed out the error, also had the template that
works.I would like to use this template all the time, but I am not
quite sure, what it is exactly doing. It is trying to get a reference
to an array and then get the size of that array(which itself is a
reference to a char)..Not quite sure. Can somebody explain ?

template <typename T, unsigned N>
char ( & NelemArrayFunc( T ( & )[ N ] ) )[ N ];

#define Nelem( A ) (sizeof( NelemArrayFunc( A ) ))

Thanks.

Aug 3 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
I also didn't know that it was possible to do like this.
int x[5];
int y[size_of(x)]; //fails here
for me it works with g++, but doesn't with ms vc71;
.....
basicly
template <typename T, unsigned N>
char ( & NelemArrayFunc( T ( & )[ N ] ) )[ N ];

means declaration of a function that takes a reference to array of N
T's (T[N]) and returns a reference to array of N chars. (references are
used to preseve type info)

and then macro
#define Nelem( A ) (sizeof( NelemArrayFunc( A ) ))
uses sizeof NelemArrayFunc( A ); where NelemArrayFunc is only valid for
arrays. When this function used as an argument to sizeof the only
information used is the function's return type, that is for T[N] it
returns char[N], and sizeof(char[N]) is N

NelemArrayFunc could be written also like this:
template <typename T, unsigned N>
char ( & NelemArrayFunc( T ( & )[ N ] ) )[ N ]{
char x[N];
return x;
}
Between, anyone has a good link for info on declaration of functions
(as for such unusual declaration) and also declaration of pointers to
such functions. For example, how would I need to declare pointer to
NelemArrayFunc???

thanks

Aug 3 '05 #2

P: n/a
I think the problem is that when you pass a raw array T arr[N] to a
function as an argument the array "degrades" to a pointer T* arr. Therefore
part of the type information (N) is lost. This, however, is not the case
with type passed to class templates. And therefore with some odd looking
code we can implement size_of this way:

template <typename T, int N>
class size_calc;

template <typename T, int N>
class size_calc<T[N]>
{
public:
enum {size = N};
};

template <typename T>
int size_of(const T& t)
{
return size_calc<T>::size;
}

Notice the declaration of size_of hides the fact that t is an array from the
compiler, and hence prevents the type degrading.
Aug 4 '05 #3

P: n/a
My previous post is completely stupid. Forget it.

Here is what I should have posted:

template <typename T, int N>
int size_of (const T (&arr) [N])
{
return N;
}
Aug 4 '05 #4

P: n/a
__PPS__ wrote:
....


Between, anyone has a good link for info on declaration of functions
(as for such unusual declaration) and also declaration of pointers to
such functions. For example, how would I need to declare pointer to
NelemArrayFunc???


template <typename T, unsigned N>
char ( & NelemArrayFunc( T ( & )[ N ] ) )[ N ];

char ( & (* XNelemArrayFunc)( int ( & )[ 3 ] ) )[ 3 ];

XNelemArrayFunc = & NelemArrayFunc<int, 3>;
Aug 6 '05 #5

P: n/a
benben wrote:
I think the problem is that when you pass a raw array T arr[N] to a
function as an argument the array "degrades" to a pointer T* arr. Therefore
part of the type information (N) is lost. This, however, is not the case
with type passed to class templates. And therefore with some odd looking
code we can implement size_of this way:

template <typename T, int N>
class size_calc;

template <typename T, int N>
class size_calc<T[N]>
{
public:
enum {size = N};
};

template <typename T>
int size_of(const T& t)
{
return size_calc<T>::size;
}

Notice the declaration of size_of hides the fact that t is an array from the
compiler, and hence prevents the type degrading.


return is a run-time expression. sizeof is a compile-time expression so
it can be used wherever a constant is needed.

Aug 6 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.