Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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)

like image 538
Steven Lu Avatar asked Jul 16 '14 14:07

Steven Lu


People also ask

Which is the efficient way of concatenating the string in Java?

StringBuilder is the winner and the fastest way to concatenate Strings. StringBuffer is a close second, because of the synchronized method, and the rest of them are just 1000 times slower than them.

What happens when concatenating strings?

Concatenation is the process of appending one string to the end of another string. You concatenate strings by using the + operator. For string literals and string constants, concatenation occurs at compile time; no run-time concatenation occurs. For string variables, concatenation occurs only at run time.

What is concatenate in Ruby?

Concatenating strings or string concatenation means joining two or more strings together. In Ruby, we can use the plus + operator to do this, or we can use the double less than operator << .


1 Answers

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;
}
like image 125
pdw Avatar answered Nov 03 '22 14:11

pdw