What's wrong with asking the compiler how big the array is - it knows, it bunged the thing on the stack for you:
template <typename T, std::size_t N>
std::size_t sizeof_array( T (&)[N] )
{
return N;
}
Most decent compilers (VC++2003, 2005, 2008 and 2010, gcc 3.3 onwards) will inline that to a constant. You can extend it a bit...
template <typename T, std::size_t N>
T *beginning_of_array( T (&a)[N] )
{
return a;
}
template <typename T, std::size_t N>
T *end_of_array( T (&a)[N] )
{
return &a[ N ];
}
which means you can get away from using indexes entirely and start using algorithms to do the sort of thing you're doing in your example:
int main()
{
std::string a[] = { "One", "Two", "Three" };
std::copy( beginning\_of\_array( a ), end\_of\_array( a ), std::ostream\_iterator<std::string>( std::cout, "\\n" ) );
}
From there you're not far away from using overloaded functions to come up with a generic way of handling different aggregates of things. Cheers, Ash