コンパイル時に文字列を結合する
コンパイル時に使える文字列型のようなものを用意します。
2つの文字列を受け取る際に、templateでその文字列長を推論して得られるようにしておき、あとはindex_tuple idiomを用いて結合処理をして新しい文字列型を返します。
このようにすれば、副作用を用いずに2つの文字列を結合することが出来ます。
どうすればうまくいくか判ったところで、実際にコンパイル時文字列を使用したい場合はsprout::stringを使えば良いと思います。
#include <type_traits> #include <sprout/index_tuple.hpp> template<class T, std::size_t N> struct c_str { public: T value[N ? N : 1]; template<class T1, std::size_t N1> constexpr bool operator==(T1(&str)[N1]) const { return N == N1 && cmp_impl(str); } private: template<class T1, std::size_t N1> constexpr bool cmp_impl(T1(&str)[N1], std::size_t step = 0, bool result = true) const { return step < N1 ? cmp_impl(str, step + 1, result && value[step] == str[step]) : result ; } }; template<class T, std::size_t size1, std::size_t size2, sprout::index_t... indexes> constexpr auto cat_impl(const T (&str1)[size1], const T (&str2)[size2], sprout::index_tuple<indexes...>) -> decltype( c_str<T, size1 + size2 - 1>{{(indexes < (size1 - 1) ? str1[indexes] : str2[indexes - (size1 - 1)])...}} ) { return c_str<T, size1 + size2 - 1>{{(indexes < (size1 - 1) ? str1[indexes] : str2[indexes - (size1 - 1)])...}}; } template<class T, std::size_t size1, std::size_t size2> constexpr auto cat(const T (&str1)[size1], const T (&str2)[size2]) -> decltype( cat_impl(str1, str2, typename sprout::index_range<0, size1 + size2 - 1>::type()) ) { return cat_impl(str1, str2, typename sprout::index_range<0, size1 + size2 - 1>::type()); } int main() { constexpr auto str1 = cat("Hello, ", "World!"); static_assert(str1 == "Hello, World!", ""); }