The best I can think of requires you to use something like:
(Update: Thanks to dyp's comment the usage became slightly less verbose but it now works at block scope!)
template< char... > struct foo {};
struct hallo { static constexpr const char* str() { return "Hallo"; } };
make< foo, hallo > m;
where make< foo, hallo >
expands to foo< 'H', 'a', 'l', 'l', 'o' >
. It's C++11 and works with recent versions of GCC and Clang (haven't tested others).
Live example
Here's the technique which, unlike other solutions you will find, does not require any macros and it does not have any limit on the length of the string.
It starts with the usual indices helper (this is already available in C++14):
template< std::size_t... Ns >
struct indices
{
using next = indices< Ns..., sizeof...( Ns ) >;
};
template< std::size_t N >
struct make_indices
{
using type = typename make_indices< N - 1 >::type::next;
};
template<>
struct make_indices< 0 >
{
using type = indices<>;
};
and now the main technique:
constexpr std::size_t length( const char* str )
{
return *str ? ( length( str + 1 ) + 1 ) : 0;
}
template< template< char... > class C,
typename T,
typename = typename make_indices< length( T::str() ) >::type >
struct make_impl;
template< template< char... > class C,
typename T,
std::size_t ... Is >
struct make_impl< C, T, indices< Is... > >
{
using type = C< T::str()[ Is ]... >;
};
template< template< char... > class C, typename T >
using make = typename make_impl< C, T >::type;