Предположим, у меня есть шаблонный класс base
и класс wrapper
, который содержит экземпляр класса base
. Я хотел бы определить класс wrapper
так, чтобы он зависел от пакета параметров шаблона, который просто «передается» в экземпляр элемента base
.
Например, рассмотрим следующий код, который отлично работает.
#include <iostream>
template <int i, int j>
struct base {
base()
{
std::cout << "i is " << i;
std::cout << " j is " << j << std::endl;
}
};
template <int... T>
struct wrapper {
base<T...> a;
};
int main()
{
wrapper<2, 3> x;
return 0;
}
Заранее зная, что все параметры шаблона base
равны int
, я использую template <int...T>
в объявлении wrapper
. Это обеспечивает ограниченную гибкость, например, я мог бы определить некоторые значения по умолчанию для параметров шаблона base
, без изменения wrapper
.
Однако, если base
зависит от произвольного списка типовых и нетиповых параметров шаблона, как я могу передать параметры шаблона wrapper
в base
?
Например, если я знаю, что все параметры шаблона base
могут быть неявно преобразованы в int (без потерь!), Я мог бы определить wrapper
как в следующей программе
#include <iostream>
template <int i, bool j>
struct base {
base()
{
std::cout << "i is " << i;
std::cout << " j is " << (j ? "true" : "false") << std::endl;
}
};
template <int... T>
struct wrapper {
base<T...> a;
};
int main()
{
wrapper<2, true> x;
return 0;
}
Но если base
зависит в то же время от типовых и нетиповых параметров шаблона, как в следующей программе, очевидно, невозможно просто передать параметры шаблона wrapper
в base
:
#include <iostream>
template <class U, int i, int j>
struct base {
base()
{
std::cout << "i is " << i;
std::cout << " j is " << j << std::endl;
}
};
template <class... T>
struct wrapper {
base<T...> a;
};
int main()
{
wrapper<int, 2, 3> x; // Error!
return 0;
}
Эта программа не компилируется, потому что компилятор ожидает типы для wrapper
.
Есть ли способ написать класс wrapper
, который "передает" параметры своего шаблона элементу типа base
, , независимо от того, что они ?
Идея состоит в том, чтобы иметь общий код для wrapper
, который не нужно изменять, если, скажем, изменяется шаблонная подпись base
.