You can avoid the loop by using some meta-programming. The idea is to unfold the loop at compile-time:
First, use a reference to avoid an array-to-pointer decay. That way, you can deduce the size of the array. You use the size to generate a compile-time std::size_t
sequence going from 0 to size-1 and feed the array and the sequence to an implementation function:
template <std::size_t N>
std::string to_string(int (&array)[N]) {
return to_string_impl(array, std::make_index_sequence<N>());
}
In that second function, you use parameter pack expansion to generate an unfolded loop:
template <std::size_t N, std::size_t... Ns>
std::string to_string_impl(int (&array)[N], std::index_sequence<Ns...>) {
std::ostringstream os;
std::ostream_iterator<int> out(os, " ");
int dummy[sizeof...(Ns)] = { (os << array[Ns], 0)... };
/* generates:
os << array[0]
...
os << array[N-1]
*/
return os.str();
}
NB: don't forget to include:
#include <iostream>
#include <utility>
#include <sstream>
#include <iterator>
Then you have it:
int main() {
int arr[] = {1,2,3,4,5};
std::cout << to_string(arr); // prints "12345"
}