Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ template string concatenation

I'm trying to define some variadic template like that:

typedef const char CCTYPE[];
template<CCTYPE X, CCTYPE... P> struct StringConcat { ... };

so that I could write sth like:

char foo[] = "foo"; char bar[] = "bar";
std::cout << StringConcat<foo, bar>;

and it printed foobar. How can I do this, if it's possible in C++0x?

my real interest is to solve FizzBuzz problem using c++ templates, I found a solution here to convert an int to char[] using templates.

like image 879
vissi Avatar asked Jan 14 '11 17:01

vissi


3 Answers

#include <boost/mpl/string.hpp>
#include <boost/mpl/insert_range.hpp>
#include <boost/mpl/end.hpp>
#include <iostream>

using namespace boost;

template < typename Str1, typename Str2 >
struct concat : mpl::insert_range<Str1, typename mpl::end<Str1>::type, Str2> {};

int main()
{
  typedef mpl::string<'hell', 'o'> str1;
  typedef mpl::string<' wor', 'ld!'> str2;

  typedef concat<str1,str2>::type str;

  std::cout << mpl::c_str<str>::value << std::endl;

  std::cin.get();
}

Using that construct you should be able to implement your FizzBuzz in pure metaprogramming. Nice exercise BTW.

like image 142
Edward Strange Avatar answered Nov 15 '22 17:11

Edward Strange


You can solve the problem of making your std::cout << StringConcat<foo, bar> work.

template<CCTYPE...> struct StrBag {};
template<CCTYPE ...Str> void StringConcat(StrBag<Str...>) {}

std::ostream &print(std::ostream &os) { 
  return os; 
}

template<typename ...T> 
std::ostream &print(std::ostream &os, CCTYPE t1, T ...t) { 
  os << t1; 
  return print(os, t...);
}

template<CCTYPE ...Str>
std::ostream &operator<<(std::ostream &os, void(StrBag<Str...>)) {
  return print(os, Str...) << std::endl;
}

Now you can say

char foo[] = "foo"; char bar[] = "bar";
int main() {
  std::cout << StringConcat<foo, bar> << std::endl;
}

Hope it helps.

like image 5
Johannes Schaub - litb Avatar answered Nov 15 '22 16:11

Johannes Schaub - litb


Impossible. foo and bar are not compile time constants. There is also no reason to do this when you can use plain old functions:

char foo[] = "foo"; char bar[] = "bar";
std::cout << StringConcat(foo, bar);
like image 1
Yakov Galka Avatar answered Nov 15 '22 17:11

Yakov Galka