Шаблон переменной шаблона?

Допустим, у вас есть тип кортежа, и вы хотите извлечь его пакет параметров шаблона, чтобы создать экземпляр другого шаблона. Если это шаблон типа, то у меня может быть такая утилита:

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...>;
};

2 ответа

Решение

Я не думаю, что вы можете сделать это. Цитата 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.

Другие вопросы по тегам