Итак, во-первых, извинения за терминологию - я не уверен, что прототип шаблона - правильный термин. Под этим я подразумеваю:Прохождение шаблона шаблона в качестве аргумента шаблона - возможно ли это?
template <class T, class X>
class TemplatePrototype
{
// code
};
У меня есть ситуация, когда у меня есть функция, которая создает объект шаблона на основе аргументов шаблона этой функции.
template <class T, class X>
void doSomething()
{
TemplatePrototype<T, X> aTemplateTX;
aTemplateTX.doSomethingElse();
}
Однако, существует около 15 различных версий TemplatePrototype, которые все имеют один и тот же интерфейс, но различное исполнение (TemplatePrototype предоставляется другой библиотекой). В результате, у меня есть много кода, который выглядит следующим образом:
template <class T, class X>
void doSomethingWithOne()
{
TemplatePrototypeOne<T, X> aTemplateTX;
aTemplateTX.doSomethingElse();
}
template <class T, class X>
void doSomethingWithTwo()
{
TemplatePrototypeTwo<T, X> aTemplateTX;
aTemplateTX.doSomethingElse();
}
Как следствие архитектуры, я нужно обязательно знать, какие TemplatePrototype я собираюсь использовать , прежде чем я знаю фактические типы T и X. Я бы как, чтобы увидеть что-то вроде этого:
template <class T, class X, class Prototype>
void doSomething()
{
Prototype<T, X> aPrototype;
aPrototype.doSomething();
}
Но где я определенную часть аргументов шаблона заранее - т.е. я указываю Prototype Befo re Я знаю T и X. Очевидно, что это невозможно в C++.
В равной степени я не могу передать Prototype в качестве аргумента шаблона, потому что он все равно приведет к огромному количеству дубликатов кода.
Некоторые важные факты: Я знаю диапазон всех возможных входов.
Так что я мог бы теоретически использовать макрос, чтобы определить каждую возможную специализацию по шаблону и вставить их в контейнер, который я бы использовал для доступа к специализации, в которой я нуждаюсь. Тем не менее, я ищу более «элегантное» решение - можно ли пропустить шаблонные прототипы, не специализируясь на них как аргумент класса шаблона, а затем создавать экземпляры позже, когда вызывается функция? Пример:
template <class Prototype>
class Holder
{
template <class T, class X>
void doSomething()
{
Prototype<T, X> aPrototype;
aPrototype.doSomethingElse();
}
};
Насколько я знаю, что это невозможно, но мне было интересно, если SO сообщество некоторые люди, которые знают решение?
EDIT:
Так что я реализовал это, как мое решение, благодаря ответы на приведенные ниже!
#include <iostream>
template <typename T>
struct Foo
{
Foo() { aPtr = 0; }
T* aPtr;
};
template <template<typename> class C>
struct Bar
{
template <class T>
void doSomething()
{
C<T> aClass;
if (aClass.aPtr)
std::cout << "Hello world" << std::endl;
}
};
int main()
{
Bar<Foo> aFoo;
aFoo.doSomething<int>();
return 0;
}
Это позволяет мне определить, какие TemplatePrototype я хотел бы использовать, перед тем я могу знать параметры шаблона.
Существует такая вещь, как параметры шаблона шаблона: один можно написать 'шаблон <шаблон <класс, класс> класс Prototype> ... { Prototype ...} ' –
ach
Обратите внимание: параметры' template' 'template'ы кажутся очень удобными, пока вы не попытаетесь использовать их в нетривиальном виде. Затем вы начинаете сталкиваться с проблемами, вызванными фактами: (1) фиксировано количество шаблонных параметров для шаблона и (2) тип класса теперь полностью исправлен. Не стесняйтесь дать им попробовать, но имейте в виду, что вам может понадобиться найти другое решение. – Mehrdad
@Mehrdad Нет, их количество не фиксировано. Существуют различные шаблонные параметры шаблона;) См. Мой обновленный ответ. – leemes