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

аюсь определить некоторый шаблон variadic как это:

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 [], используя шаблоны.

 Chan14 янв. 2011 г., 18:14
Что не так с передачей этих двух строк в качестве обычных параметров?
 vissi14 янв. 2011 г., 18:16
Это не проблема для регулярного объединения строк, я хотел бы сделать это, используя только шаблоны, я добавил параграф, который описывает, что я делаю.

Ответы на вопрос(5)

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

е нет причин делать это, когда вы можете использовать простые старые функции:

char foo[] = "foo"; char bar[] = "bar";
std::cout << StringConcat(foo, bar);
 ybungalobill14 янв. 2011 г., 18:35
@ Конрад: это не очевидно из вопроса, где эти массивы расположены. Если они локальные, то они не являются постоянной времени компилятора. Их содержаниене постоянный в любом случае.
 Konrad Rudolph14 янв. 2011 г., 20:13
верно по обоим пунктам.
 Konrad Rudolph14 янв. 2011 г., 18:18
(1) массивынаходятся константы времени компиляции (или, скорее, это внешние символы, которые могут распадаться на указатели, которые, в свою очередь, могут использоваться как константы времени компиляции). Как их содержание. В противном случае код, указанный в вопросе, также не будет работать. (2) Причина теперь сформулирована в вопросе: любопытство. Мощная причина.
 vissi14 янв. 2011 г., 18:18
Единственный способ передать строковый литерал в шаблон описан здесь:comeaucomputing.com/techtalk/templates/#stringliteral
Решение Вопроса
#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 в чистом метапрограммировании. Хорошее упражнение Кстати.

 vissi14 янв. 2011 г., 20:20
Тем не менее, я не могу сделать этоpastebin.com/CjT0iSRw работай. Если вы замените 8 на 7 в main (), все в порядке, иначе он не скомпилируется. Кажется, что некоторые ограничения реализации mpl, не может выполнять более 7 конкатенаций.
 vissi14 янв. 2011 г., 18:28
Спасибо! Поскольку boost :: mpl - это чистая библиотека шаблонов, это то, что я могу использовать.
 Crazy Eddie14 янв. 2011 г., 21:04
Вам нужно увеличить максимальную длину строки mpl :: string, установив BOOST_MPL_LIMIT_STRING_SIZE перед тем, как включать заголовок (это версия переменных шаблонов C ++ 03..процессор построен). Вы достигнете максимального максимума в BOOST_PP_LIMIT_MAG-3 и, возможно, максимальной глубины макросов ваших компиляторов до этого. Мне удалось установить 150, но не 200. Возможно, вам придется изменить проблему одним касанием, чтобы сделать это возможным. В любом случае, 100 итераций не являются ключевой частью проблемы. Похоже, вы могли бы решить это в любом случае ...

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

Вы можете решить проблему создания вашего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;
}

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

 Chan14 янв. 2011 г., 18:44
Шауб: Большое спасибо;)!
 Johannes Schaub - litb14 янв. 2011 г., 18:41
@Chan, это было предназначено, чтобы быть полным решением. Видетьideone.com/LzO5Y , Вам не нужно извиняться за вопрос :) Я просто вижу, что не получаю гарантированный порядок оценки, так что ideone справедливо выводит "barfoo" :) Позвольте мне исправить это.
 Chan14 янв. 2011 г., 18:39
Шауб: Интересно, было ли это полное решение? потому что я не мог получить ваш код скомпилирован. Извините за мои ограниченные знания.

Ваш ответ на вопрос