我正在尝试编写一个带有可变参数模板参数包的类模板,该参数包分为两组参数。这些应在会员模板中使用。
template <class... Args>
class Foo {
public:
Foo(const Args&... args) :gr1{/*...*/}, gr2{/*...*/} {}
private:
template_one<Group1...> gr1;
template_two<Group2...> gr2;
};
我想出的是:
一个类型排序器,它返回一对包含排序类型的元组。
template <typename... Args>
struct type_sorter;
template <>
struct type_sorter<> {
constexpr static auto sort() {return std::pair<std::tuple<>, std::tuple<>>{}; }
};
template <typename Arg, typename... Args>
struct type_sorter<Arg, Args...> {
constexpr static auto sort() {
auto ret = type_sorter<Args...>::sort();
if constexpr (std::is_function_v<Arg>)
return std::make_pair(std::tuple_cat(ret.first, std::tuple<Arg*>{}), ret.second);
else
return std::make_pair(ret.first, std::tuple_cat(ret.second, std::tuple<Arg>{}));
}
};
一个 param sorter 返回一对包含排序类型和参数的元组。
template <class Arg>
constexpr auto param_sort(Arg&& arg) {
if constexpr (std::is_function_v<typename std::remove_reference_t<Arg>>)
return std::make_pair(std::tuple<Arg>(arg), std::tuple<>());
else
return std::make_pair(std::tuple<>(), std::tuple<Arg>(arg));
}
template <class Arg, class... Args>
constexpr auto param_sort(Arg&& arg, Args&&... args) {
auto ret = param_sort(std::forward<Args>(args)...);
if constexpr (std::is_function_v<typename std::remove_reference_t<Arg>>)
return std::make_pair(std::tuple_cat(ret.first, std::tuple<Arg>(arg)), ret.second);
else
return std::make_pair(ret.first, std::tuple_cat(ret.second, std::tuple<Arg>(arg)));
}
目前 std::is_function 是排序标准。 前者可用于对类型进行排序,而无需提供参数,而后者可对模板参数和参数进行排序。当只能访问模板参数包时,这非常有用。 (在课堂范围内。)
现在他们都返回元组:
我希望能够从 type sorter 生成的元组中提取参数包(Group1、Group2),并在 template_one 和 template_two 的声明中使用它。
我尝试的是:
template_one<decltype(std::get<
std::make_index_sequence<std::tuple_size_v<
decltype(type_sorter<Inputs...>::sort().second)
>>>(type_sorter<Inputs...>::sort().second)...)
> gr1 {};
不起作用
这样的事情可能吗?
使用委托构造函数,您可能会这样做:
template <class... Args>
class Foo {
using Tuple1 = decltype(type_sorter<Args...>::sort())::first_type;
using Tuple2 = decltype(type_sorter<Args...>::sort())::second_type;
Foo(const std::pair<Tuple1, Tuple2>& p) :gr1{p.first}, gr2{p.second} {}
public:
Foo(const Args&... args) : Foo(param_sort(args...)) {}
private:
Tuple1 gr1;
Tuple2 gr2;
};
如果我正确理解了这个问题,您正在寻找一种方法来获得
foo<A...>
给出一些 std::tuple<A...>
。
你可以为此写一个特质:
template <template <typename ...> class T,typename A>
struct tuple_expander;
template <template <typename ...> class T,typename ...B>
struct tuple_expander<T,std::tuple<B...>> {
using type = T<B...>;
};