I would like to initialize constexpr char[] member with another constexpr char [] member. Is it possible to do in C++11 or above?
Starting from C++14 you can use std::make_index_sequence and std::index_sequence.
If it's OK for you works in a ValueOneHolder specialization, you first can develop a constexpr function that, given a C-style array, return the size of the array
template <typename T, std::size_t N>
constexpr std::size_t getDim (T const (&)[N])
{ return N; }
Nest you can declare ValueOneHolder adding a second template parameter with a default value that is an index sequence corresponding to T::ValueOne
template <typename T,
typename = std::make_index_sequence<getDim(T::ValueOne)>>
struct ValueOneHolder;
and last the easy part: the partial specialization with initialization
template <typename T, std::size_t ... Is>
struct ValueOneHolder<T, std::index_sequence<Is...>>
{ static constexpr char Value[] = { T::ValueOne[Is] ... }; };
Don't forget the following line, outside the struct
template <typename T, std::size_t ... Is>
constexpr char ValueOneHolder<T, std::index_sequence<Is...>>::Value[];
The following is a full C++14 compiling example
#include <utility>
#include <iostream>
struct Base
{
static constexpr char ValueOne[] = "One";
static constexpr char ValueTwo[] = "Two";
};
template <typename T, std::size_t N>
constexpr std::size_t getDim (T const (&)[N])
{ return N; }
template <typename T,
typename = std::make_index_sequence<getDim(T::ValueOne)>>
struct ValueOneHolder;
template <typename T, std::size_t ... Is>
struct ValueOneHolder<T, std::index_sequence<Is...>>
{ static constexpr char Value[] = { T::ValueOne[Is] ... }; };
template <typename T, std::size_t ... Is>
constexpr char ValueOneHolder<T, std::index_sequence<Is...>>::Value[];
int main()
{
std::cout << ValueOneHolder<Base>::Value << std::endl;
}
If you want a C++11, you can develop a substitute for std::make_index_sequence and std::index_sequence.
std::arrayinstead?