std :: for_each "iterates" over a range, so to use it with an array of indefinite length you need to use custom iterators to signal the end of the array (on a NULL member). If you insist on using the NULL-end char * array, you can, of course, create your own for_each function for it, for example, for example:
template <typename Function> void for_each_in_null_terminated_cstring_array(const char** array, Function f) { while (*array) { f(*array); array++; } } const char *names[] = { "Bob", "Adam", "Simon", NULL }; for_each_in_null_terminated_cstring_array(names, func);
I do not recommend this solution.
edit: Yes, a more general one is always better, isn't it?
template <typename T, typename Function> void for_each_in_null_terminated_array(T* array, Function f) { while (*array) { f(*array); array++; } }
(Here's the implementation of the null-terminated (false-terminated) iterator that I mentioned earlier with a change or two based on the suggestions below. It should be a real InputIterator)
template <class T> class nt_iterator: public std::iterator<std::input_iterator_tag, T> { public: typedef typename nt_iterator<T>::pointer pointer; typedef typename nt_iterator<T>::value_type value_type; nt_iterator(): p(), pte(true) {} nt_iterator(pointer p_): p(p_), pte(!p_) {} nt_iterator(const nt_iterator<T>& rhs): p(rhs.p), pte(rhs.pte) {} nt_iterator<T>& operator++() { ++p; if (!*p) pte = true;
And how is it used:
void print(const char* str); int main() { const char* array[] = {"One", "Two", "Three", NULL, "Will you see this?"}; std::for_each(nt_iterator<const char*>(array), nt_iterator<const char*>(), print); }
It is probably a little slower than the version of the loop, due to the increased number of equivalence checks - the difference in speed is, of course, insignificant compared, for example, with the text, but it should be noted that std::for_each does not magically do (actually in fact, you may be surprised to see how your compiler provider defines a function, that is, if you expect too much).