Конкатенация строк шаблона C ++ - PullRequest
10 голосов
/ 14 января 2011

Я пытаюсь определить какой-нибудь вариационный шаблон следующим образом:

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

чтобы я мог написать что-то вроде:

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

и напечатано foobar. Как я могу это сделать, если это возможно в C ++ 0x?

Мой реальный интерес - решить проблему FizzBuzz с помощью шаблонов c ++. Я нашел решение здесь для преобразования int в char [] с использованием шаблонов.

Ответы [ 5 ]

5 голосов
/ 14 января 2011
#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();
}

Используя эту конструкцию, вы сможете реализовать FizzBuzz в чистом метапрограммировании.Хорошее упражнение.

5 голосов
/ 14 января 2011

Вы можете решить проблему с работой std::cout << StringConcat<foo, bar>.

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;
}

Теперь вы можете сказать

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

Надеюсь, это поможет.

0 голосов
/ 14 января 2011

Вы не можете объединить два или более строковых литералов, ожидающих получить один строковый литерал (если вы не хотите использовать макросы).Но в зависимости от поставленной задачи вы можете вернуть функцию-шаблон, например, std :: string, которая представляет собой конкатенацию строковых литералов.Последнее тривиально.

0 голосов
/ 14 января 2011

Можно взять переменное количество символов.Тем не менее, я считаю, что не существует способа объединения строк, определенных таким образом.

0 голосов
/ 14 января 2011

Невозможно.foo и bar не являются константами времени компиляции.Также нет причин делать это, когда вы можете использовать простые старые функции:

char foo[] = "foo"; char bar[] = "bar";
std::cout << StringConcat(foo, bar);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...