распаковка аргументов variadic template для определения новых аргументов шаблона
Я новичок в программировании шаблонов, и у меня есть два вопроса...Надеюсь, кто-то может мне помочь. Я пытаюсь использовать шаблоны с переменным числом аргументов, чтобы создать новый вход в другой шаблон с переменным числом аргументов. Другими словами, у меня есть класс
template <std::size_t N, std::size_t... M>
class Class1 {
}
Я хочу использовать целочисленные значения, представленные N, M, чтобы создать новый набор входных данных типа std::bitset для другого шаблонного класса
template <typename T, typename... Ts>
class Class2 {
}
так, например, если я использую Class1<10,20,25>
Я хочу внутри тела Class1
в
создать
Class2<std::bitset<10>, std::bitset<20>, std::bitset<25>>
переменная. Есть ли простой способ сделать это с помощью C++11?
мой второй вопрос заключается в том, как я могу абстрагировать это еще больше, чтобы распаковка не была специфичной для std::bitset
класса?
Есть ли способ изменить Class1
определение шаблона, чтобы я мог расширить некоторый произвольный шаблонный класс, который я разрабатываю вместо std::bitset
?
3 ответов
вы можете написать что-то вроде:
template <std::size_t N, std::size_t... M>
class Class1 {
template <template <typename, typename...> class C,
template <std::size_t> class inner>
using rebind_with_type = C<inner<N>, inner<M>...>;
};
а то
Class1<10, 20, 25>::rebind_with_type<Class2, std::bit_set>
// -> Class2<std::bit_set<10>, std::bit_set<20>, std::bit_set<25>>
и если вызовите его с зависимым именем, не забудьте typename
/template
:
typename Class1<N, M...>::template rebind_with_type<Class2, std::bit_set>
// -> Class2<std::bit_set<N>, std::bit_set<M>...>
Я нахожу, что вы можете думать об этом ... оператор на пакетах параметров таким образом:
f(g(Xs)...);
расширится до
f(g(Xs1), g(Xs2), ..., g(Xsn));
для любых операций f и g. На самом деле все, что он делает, это добавляет разделенный запятыми список g, применяемый к каждому из предоставленных параметров. Этот... определяет, где должно начаться расширение Эти операции могут быть для типов или значений, поэтому в вашем случае наш f-Class2<...> и наш г СТД:: битсет наш тип посмотрел бы как
Class2<std::bitset<N>, std::bitset<M>...>
первый должен быть явно добавлен, так как он не является частью пакета параметров ofcourse.
другие ответы превосходны, но позвольте мне дать вам еще более общую версию принятого ответа. Вы в основном создаете псевдоним using, который принимает два шаблона, первый-это класс, который будет содержать шаблоны классов в качестве параметров шаблона ,а второй-шаблон (например,bitset
), в который вы хотите передать типы.
template<template<class...> class Y, template<class...> class Z, class... Ts>
using fold_types_into_t = Y<Z<Ts>...>;
template<template<class...> class Y, template<auto...> class Z, auto... Vs>
using fold_values_into_t = Y<Z<Vs>...>;
template<class,class...>
struct Class2;
template <std::size_t N, std::size_t... M>
class Class1 {
// Class2<std::bitset<10>, std::bitset<20>, std::bitset<25>>
using T=fold_values_into_t<Class2, std::bitset, N, M...>;
};
также может быть добавлена поддержка классов, которые принимают значения, а также типы.