Concatenate compile-time strings in a template at compile time?

c++, c++11, string, template-meta-programming, templates

Solution

You could use something like this. Everything happens at compile time. Specialize base_typename_struct to define your primitive types.

template <const char* str, int len, char... suffix>
struct append {
  static constexpr const char* value() {
    return append<str, len-1, str[len-1], suffix...>::value();
  }
};

template <const char* str, char... suffix>
struct append<str, 0, suffix...> {
  static const char value_str[];
  static constexpr const char* value() {
    return value_str;
  }
};

template <const char* str, char... suffix>
const char append<str, 0, suffix...>::value_str[] = { suffix..., 0 };


template <typename T>
struct base_typename_struct;

template <>
struct base_typename_struct<int> {
  static constexpr const char name[] = "int";    
};


template <typename T, char... suffix>
struct typename_struct {
  typedef base_typename_struct<T> base;
  static const char* name() {
    return append<base::name, sizeof(base::name)-1, suffix...>::value();
  }
};

template <typename T, char... suffix>
struct typename_struct<T*, suffix...>:
  public typename_struct<T, '*', suffix...> {
};


int main() {
  cout << typename_struct<int****>::name() << endl;
}

Problem

Currently I have: ``` template <typename T> struct typename_struct<T*> { static char const* name() { return (std::string(typename_struct<T>::name()) + "*").c_str(); } }; ``` I wonder if I can avoid the whole bit where I'm forced to allocate a string to perform the concatenation. This is all happening at compile time, i.e. I intend to get the string `"int****"` when I reference `typename_struct<int****>::name()`. (Do assume that I have declared a corresponding specialization for `int` which returns `"int"`) As the code is written now, does the compiler do the concatenation with std::string during compile time only? (I would be okay with that) Or does such a call result in 4 std::string based concatenations at runtime? (I would not be okay with that)

Original source

Related problems