There is zero need for template recursion here, or even templates at all.
The functionality can be computed as a simple constexpr function.
A string as a char template parameter pack is a textbook example of an antipattern.
The functionality can be computed as a simple constexpr function.
A string as a char template parameter pack is a textbook example of an antipattern.
A place where this kind of pattern is useful is in having a generic accessor type for fields, and wanting to extend it to tuples. So for example accessor(x) might return x.field, and accessor.name might be "field." To make it work for tuples, you need a string for every possible tuple index. E.g.:
template<typename T, size_t N> struct tuple_accessor;
template<typename...T, size_t N>
struct tuple_accessor<std::tuple<T...>, N> {
constexpr decltype(auto) operator(auto &&t) const {
return get<N>(std::forward<decltype(t)>(t));
}
static constexpr const char *name = index_string<N>();
}; #include <array>
#include <tuple>
constexpr std::array<char, 11> itos(unsigned n) {
std::array<char, 11> s;
unsigned i = 0;
while (n) {
s[i++] = '0' + (n % 10);
n /= 10;
}
s[i] = '\0';
return s;
}
template<auto V>
struct static_value {
static constexpr auto value = V;
};
template<class T, unsigned N>
struct tuple_accessor;
template<class...T, unsigned N>
struct tuple_accessor<std::tuple<T...>, N> {
static constexpr const char *name = static_value<itos(N)>::value.data();
};tuple_accessor::name is a const char* which is what you asked for. static_value here is an implementation detail and the type of its members is irrelevant.