Допустим, у вас есть тип кортежа, и вы хотите извлечь его пакет параметров шаблона, чтобы создать экземпляр другого шаблона. Если это шаблон типа, то у меня может быть такая утилита:
template < typename Tuple, template <typename...> typename What >
struct PutTupleInT;
template < typename... Types, template <typename...> typename What >
struct PutTupleInT<std::tuple<Types...>, What>
{
using Result = What<Types...>;
};
Но что, если желаемый шаблон является переменным шаблоном? В то время как template <typename...> typename What
такое «заполнитель» для шаблона типа, тогда что такое «заполнитель» для шаблона переменной?
Я попробовал следующее для clang-4.0.0 (единственный компилятор, который поддерживает не типовые параметры шаблона с автоматическим типом), но это не удалось. На самом деле я не уверен, что это правильный синтаксис для C ++ 17.
template < typename Tuple, template <typename...> auto What >
struct PutTupleInV;
template < typename... Types, template <typename...> auto What >
struct PutTupleInV<std::tuple<Types...>, What>
{
static constexpr auto value = What<Types...>;
};
Я не думаю, что вы можете сделать это. Цитата N4606:
§14.3.3 [temp.arg.template] / 1
Шаблон-аргумент для шаблона Шаблон-параметр должен быть
имя шаблона класса или шаблона псевдонима, выраженное как
ID-выражение.
Шаблон переменной не соответствует этому требованию.
Вы можете немного обмануть и использовать тип прокси, чтобы выбрать шаблон:
template < typename Tuple, class Proxy>
struct PutTupleInTV;
template < typename... Types, class Proxy>
struct PutTupleInTV<std::tuple<Types...>, Proxy>
{
static constexpr auto value = Proxy::template value<Types...>;
};
а затем для
template<typename...> struct foo{};
template<typename... Ts> constexpr foo<Ts...> foo_v{};
struct use_foo
{
template<typename... Ts>
static constexpr auto value = foo_v<Ts...>;
};
ты мог бы сказать
PutTupleInTV<tup, use_foo>::value
PutTupleInTV — это не то же самое имя, что и PutTupleInV. Вы не специализируете шаблон PutTupleInV, но используете специализированный синтаксис для создания чего-то нового, называемого PutTupleInTV.