From time to time, I find myself writing code like this:
#include <algorithm>
#include <iostream>
#include <boost/lambda/lambda.hpp>
using namespace boost::lambda;
int main()
{
char const* test[] = {"Hello", "Beautiful", "World"};
std::for_each(test, test + 3, std::cout << _1 << "\n"); // interesting line
}
How do I make sure the expression "test + 3" actually marks the end of the array? After some thinking, I wrote the following pair of inline function templates:
#include <algorithm>
#include <iostream>
#include <boost/lambda/lambda.hpp>
using namespace boost::lambda;
template<typename T, size_t n>
inline T const* end_of(T const (&a)[n])
{
return a + n;
}
template<typename T, size_t n>
inline T* end_of(T (&a)[n])
{
return a + n;
}
int main()
{
char const* test[] = {"Hello", "Beautiful", "World"};
std::for_each(test, end_of(test), std::cout << _1 << "\n");
}
Now I'm almost 100% sure that hundreds of other programmers have discovered that trick before me, but I still wanted to share it with you and ask your opinion about it.
On a sidenote, do you think it's good practice to write these short const/non-const function pairs with repeated code, or should one of them be implemented in terms of the other? I seem to remember Scott Meyers had an item on that very subject. The code would then look something like this:
template<typename T, size_t n>
inline T const* end_of(T const (&a)[n])
{
return a + n;
}
template<typename T, size_t n>
inline T* end_of(T (&a)[n])
{
return const_cast<T*>(end_of(static_cast<T const (&)[n]>(a)));
}
Would you consider this good practice or over-engineering?