是否可以在成员模板中使用类模板参数包的修改版本?

问题描述 投票:0回答:2

我正在尝试编写一个带有可变参数模板参数包的类模板,该参数包分为两组参数。这些应在会员模板中使用。

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_onetemplate_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 {};

不起作用

这样的事情可能吗?

c++ metaprogramming variadic-templates template-method-pattern
2个回答
0
投票

使用委托构造函数,您可能会这样做:

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

演示


0
投票

如果我正确理解了这个问题,您正在寻找一种方法来获得

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

现场演示

© www.soinside.com 2019 - 2024. All rights reserved.