Thursday, April 10, 2008

C++ array size determination - Part 2

In my last post I showed how to create a template function to determine the size of a C++ array and promised to show how to create a template that will work with a type instead of a variable.

Lets start by looking at a struct template that through specialization we can use to capture the number of elements in an array.
  template <typename T>
struct array_info
This just names a template that we will specialize for arrays, like so:
  template <typename T, size_t N>
struct array_info<T[N]>
typedef T type;
enum { size = N };
Now we have a template that for arrays will enable us to get to the size and type of elements in the array. This can be used like so:
  typedef int IntArray[10];
size_t s = array_info<IntArray>::size; // s == 10
Or like so:
  float floatArray[array_info<IntArray>::size];
If we try something other than an array we get a compiler error.
  size_t s = array_info<int*>::size; // error
Generates a compiler error similar to:
  error: 'size' is not a member of '<unnamed>::array_info<int*>'
This is nice, but the real power is in using this with other templates. Even though I'm working with arrays one of the apis I'm using returns a pointer instead of an array reference. I know the type (which includes its length) so I wanted to take advantage of that. Here I use the array_info in an equal method to determine the length:
  template <typename A, typename T>
bool equal(const T* lhs, const T* rhs)
// Use 'typename array_info<A>::type' instead of 'T' so that compiler
// verifies A and T types match up.
const typename array_info<A>::type* const end = &lhs[array_info<A>::size];
return std::equal(&lhs[0], end, rhs, &equal_to<T>);
This template can then be used like so:
  equal<IntArray>(lhs.getVal(), rhs.getVal());
That is not syntax you get to use everyday.

C++ array size determination

My current project has me working with C-style C++ arrays. In order to make things easier and safer I created some helper templates.

Lets start with finding the the number of elements in an array. The conventional C way would be to use sizeof like:
I'm not a big fan of this approach. I have seen production code by seasoned C++ developers that looks like this:
  const char* tmp = 0;
// ...
int size = sizeof(tmp)/sizeof(tmp[0]);
Of course this is sometimes hidden behind a macro:
  #define array_size(array) (sizeof(array)/sizeof(array[0]))
// ...
int size = array_size(tmp);
Either way, this gives the wrong answer. The developer, of course, is not interested in what the size of a pointer to an element divided by the size of an element is.

So, can we do better? Actually, yes, we can.
  template <typename T, size_t N>
size_t array_size(const T (&lhs)[N])
return N;
Here we pass an array by reference to array_size() that extracts the size of the array and returns it. I talked briefly about array passing a few years ago.

We can now use it like so:
  int ia[10];
size_t s = array_size(ia); // s == 10
And if we try to use this with a pointer like so:
  const char* tmp = 0;
// ...
size_t s = array_size(tmp); // error
We get a compiler error similar to:
  error: no matching function for call to 'array_size(const char*&)'
Very nice.

However, sizeof can also be used with a type instead of a variable. In my next post, I'll show how we can create a template that will work with a type instead of a variable.

Wednesday, April 02, 2008


I'm speaking on Boost.Thread this year at BoostCon'08.

Here is the announcement from the Boost mailing list:

Reminder: early registration for BoostCon'08 closes Monday, April 7.
It's still not too late to avoid the late registration fee for what may
be the finest C++ event of 2008.

For the 2nd annual Boost C++ libraries conference, we've put together a
fantastic program crowned by a keynote address from Bjarne Stroustrup.
In addition to existing Boost libraries, we're covering technology of
interest to any C++ developer trying to stay on the cutting edge,
including hands-on sessions with features from the upcoming 2nd version
of the C++ standard. This year we've also added a collection of short
"author's corner" sessions for those of you who want an inside
perspective on how advanced libraries are developed. See for details.

BoostCon 2008 will be hosted at Aspen Center for Physics, one of the
most beautiful meeting sites in the world, and a great venue for
collaboration and discovery. The combination of a relaxed pace and
intense inquiry made BoostCon'07 an event to remember, and we expect no
less for this year. Please visit
to register.


-- The BoostCon Planning Committee

David Abrahams
Beman Dawes
Jeff Garland
Joel de Guzman
Eric Niebler
Sean Parent
Jeremy Siek
Matthias Troyer