2016-10-23 4 views
8

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

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

Не можете ли вы использовать 'decltype (vartempl)' и извлечь тип шаблона переменной, что вас действительно интересует? – skypjack

+0

@skypjack Извините, я не совсем понимаю, что вы имеете в виду. – Vahagn

ответ

6

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

live demo

+0

Чит на самом деле не очень помогает, так как он требует, чтобы переменные назывались «значение» и помещались в структуру. – Vahagn

+0

@Vahagn да, вам придется создавать прокси-структуры самостоятельно. Я не вижу пути вокруг этого (не означает, что его нет, я просто ничего не знаю) – krzaq

0

PutTupleInTV не совпадает с именем PutTupleInV. Вы не специализируетесь на шаблоне PutTupleInV, а используете специальный синтаксис для создания чего-то нового, называемого PutTupleInTV.

+0

Это опечатка, спасибо за указание. – Vahagn

Смежные вопросы