У меня есть следующий класс шаблонов, в котором я хочу циклически перебирать типы шаблонов и делать что-то для каждого типа. Это упрощенный пример.
template<class... T>
class Handler
{
private:
template<class A>
void Do1_(int a, int b)
{
A obj{};
obj.Process(a, b);
}
template<class A, class... B>
void Do_(int a, int b)
{
Do1_<A>(a, b);
Do_<B...>(a, b);
}
public:
void Do(int a, int b)
{
Do_<T...>(a, b);
}
};
struct Foo1 {
void Process(int a, int b) {}
};
struct Foo2 {
void Process(int a, int b) {}
};
class Bar : public Handler<Foo1, Foo2> {};
Но расширение для Do_<B...> вызывает у меня проблемы: при компиляции Do_<B...> я получаю ошибку компиляции «не удалось вывести аргумент шаблона для 'A'». Здесь должно быть правильное расширение, чтобы оно могло скомпилироваться, если это возможно.
@Someprogrammerdude, я внес некоторые правки, чтобы сделать его убедительным примером. Где я использую неправильное многоточие?
Что такое на самом деле проблема? Этот код настолько далек от чего-то разумного, что граничит с болезненным. Была ли какая-то конкретная причина, по которой вы решили повторно использовать b в качестве идентификатора в Do1_ ??
@WhozCraig, это очень упрощенный пример, моя проблема в том, что компилятор жалуется на неправильное расширение
Do_<T..>(a, b). Возможно, это проблема у вас? Не зная, какие ошибки у вас есть (всегда включайте их!), Мы не сможем вам реально помочь.
Что означает B obj{};, учитывая, что B - это не один тип, а пакет параметров, представляющий несколько типов?
Извините, пример был ошибочным, низкий уровень сахара в крови. Теперь пример должен быть более правильным.
Вам нужна специализация Do_ для нулевых аргументов шаблона - что-то для завершения рекурсии. Но на самом деле вам вообще не нужна рекурсия: template<class... A> void Do_(int a, int b) { int dummy[] = {(Do1_<A>(a, b), 0) ...}; } Фактически, вы можете просто поместить это в Do - вам не нужны эти помощники.
Во всех ваших классах в конце отсутствует точка с запятой.





Вы слишком усложняете дело. Это должно работать (без каламбура):
template<class... T>
class Handler
{
public:
void Do(int a, int b) {
int dummy[] = {(T{}.Process(a, b), 0)...};
}
};
Спасибо. Но если бы я хотел сделать то же самое, что и сделал, как бы это сделать, если это возможно? С помощью этого решения мне пришлось бы подавить предупреждение о неиспользуемой переменной, можно ли этого избежать? И как бы вы назвали тип конструкции, которую вы использовали, я раньше не видел.
Это просто массив с инициализатором. Подобно int dummy[] = {1, 2, 3, 4};. Просто отдельные элементы инициализатора имеют побочные эффекты.
Для начала может быть хорошей идеей использование правильного многоточия с тремя точками. Как бы нам сказал какие неприятностей у вас есть. Если у вас есть ошибки сборки, скопируйте и вставьте их (в виде текста) полностью и полностью и вставьте в вопрос. То, что вы действительно должны знать как старый участник, задав несколько вопросов. Если нет, то перечитайте как задавать хорошие вопросы и заново узнайте, как создать Минимальный, полный и проверяемый пример.