2

Possible Duplicate:
Can someone explain this template code that gives me the size of an array?

template <typename T,unsigned S>
unsigned ArraySize(const T (&v)[S])
{
    return S;
}

I understand the T and S, but my question is why do we have to declare v as a reference variable? Or maybe I'm misunderstanding this whole thing.

I appreciate the help!

Community
  • 1
  • 1
quuxbazer
  • 541
  • 1
  • 4
  • 8

2 Answers2

2

The function accepts an array by reference, and because of this, type of element T and size S is deduced by the compiler. So it returns S which is nothing but the size of the array. In the absence of reference, it would decay into a pointer type. So there is no difference between these:

void f(int v[100]);  //declaration of f
void f(int v[200]);  //redeclaration of f
void f(int v[]);     //redeclaration of f
void f(int *v);      //redeclaration of f

All are exactly same. You can pass array of any size to all of these functions.


Coming back to ArraySize, the returned value of this function cannot be used as constant expression:

int a[10];
SomeClassTemplate<ArraySize(a)> obj; //error

See error : http://ideone.com/4mdJE

So a better implementation would be this:

template <typename T,unsigned S>
char (&ArraySizeHelper(const T (&v)[S]))[S];  //no need to define it!
#define ArraySize(a) sizeof(ArraySizeHelper(a))

Now this is perfectly fine:

int a[10];
SomeClassTemplate<ArraySize(a)> obj; //ok

See ok : http://ideone.com/Zt3UY

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • 1
    That's pretty awesome. And I thought I knew C++. Any suggestions for other quick reads to learn some useful tricks like these? – quuxbazer Dec 06 '11 at 06:07
  • @quuxbazer: If you want to learn more and better C++ here at stackoverflow itself, then follow these guys : [@Alf P. Steinbach](http://stackoverflow.com/users/464581/alf-p-steinbach), [Johannes Schaub - litb](http://stackoverflow.com/users/34509/johannes-schaub-litb), [MSalters](http://stackoverflow.com/users/15416/msalters), [David Rodríguez - dribeas](http://stackoverflow.com/users/36565/david-rodriguez-dribeas), [James Kanze](http://stackoverflow.com/users/649665/james-kanze), [Charles Bailey](http://stackoverflow.com/users/19563/charles-bailey) – Nawaz Dec 06 '11 at 06:17
  • @quuxbazer: And how can I forget them : [@James McNellis](http://stackoverflow.com/users/151292/james-mcnellis), [AndreyT](http://stackoverflow.com/users/187690/andreyt). Go to their profile, read the posts they've posted, including the questions they ever asked. – Nawaz Dec 06 '11 at 06:20
  • @quuxbazer: Since you're new at Stackoverflow, I would also like to redirect you to this page : [The Definitive C++ Book Guide and List](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) – Nawaz Dec 06 '11 at 06:22
2

If v wasn't a reference, then you would have this:

template <typename T,unsigned S>
unsigned ArraySize(const T v[S])
{
    return S;
}

But the use of [] in this context is just another way of writing

template <typename T,unsigned S>
unsigned ArraySize(const T *v)
{
    return S;
}

which would give you no size information.

Vaughn Cato
  • 63,448
  • 5
  • 82
  • 132