2

我正在尝试实现一种从元组中删除某些类型的方法;例如,我希望能够根据条件仅将前 2 个模板参数中的一个元组用于元组:

  1. 是否可以将元组包含的类型“打包”回参数包中?(元组 -> 类型名...包含类型)
  2. 是否可以组合一个参数。带有类型名的包(例如,使用“Pack1...,Pack2...”为结构指定单个参数包?
#include <cstdint>
#include <tuple>

template <typename... tpl> struct Helper {
  template <std::size_t rem, typename curr, typename... rest> struct take {
    using type = Helper<(tpl..., curr)>::take<rem-1, rest...>::type; // here, I'm trying (2.)
  };

  template <typename curr, typename... rest> struct take<0, curr, rest...> {
    using type = std::tuple<tpl...>;
  };
};

template <std::size_t s, typename... tpl> using take_t = Helper<>::take<s, tpl...>;

int main() {
  take_t<2, int, int, int> k = std::make_tuple(1, 2);
}

编辑行 Helper 失败并显示以下消息:

/home/juli/test.cc:6:18: error: need ‘typename’ before ‘Helper<tpl ..., curr>::take’ because ‘Helper<tpl ..., curr>’ is a dependent scope
    6 |     using type = Helper<tpl..., curr>::take<rem-1, rest...>::type;

当我提供 typename

/home/juli/test.cc:6:53: error: expected ‘;’ before ‘&lt;’ token
    6 |     using type = typename Helper<tpl..., curr>::take<rem-1, rest...>::type;

编辑2 我通过[辅助函数](https://gist.github.com/juliusHuelsmann/669f537aeb5e7105386d510d186b24e1 )实现了这一点,但是当构造函数不是 constexpr 时,那些非原始类型会失败,所以我不能在我的用例中使用它并且很好奇知道如何实现这一目标以及我的方法失败的原因。

4

1 回答 1

0

问题 2的答案 )是的,正如@user253751 所建议的那样,我的原始方法Helper<tpl..., curr>(下面的代码显示了修复并且工作正常:

#include <cstdint>
#include <tuple>

template <typename... tpl> struct Helper {
  template <std::size_t rem, typename curr, typename... rest> struct take {
    using tp = Helper<tpl..., curr>;
    using type = tp::template take<rem-1, rest...>::type;
  };

  template <typename curr, typename... rest> struct take<0, curr, rest...> {
    using type = std::tuple<tpl...>;
  };
};

template <std::size_t s, typename... tpl> using take_t = Helper<>::take<s, tpl...>;

int main() {
  take_t<2, int, int, int>::type k = std::make_tuple(1, 2);
}

问题 1的答案由此处执行的技巧给出,请参见此处的完整示例。例如,可以通过以下构造(改编自即时示例且未经测试):

template <class tuple> struct foo;

template <class ... args> struct foo<std::tuple<args...> {
    // implementation here!
};

这非常简洁,也可以用于 integer_sequence (我尝试过但直到现在都没有成功)。

可以在此处找到比我上面的初始方法更清晰的我想要实现的整个实现

template <size_t s, typename is, typename ...args> struct thlp;

template <size_t s, size_t... i, class... args> struct thlp<s, std::index_sequence<i...>, args...> {
  static_assert(s <= sizeof...(args), "Requested new tuple size exceeds old one.");
  using type = std::tuple<std::tuple_element_t<i, std::tuple<args...>>...>;
};

template <size_t s, typename... args>
using conditional_tuple_t = thlp<s, decltype(std::make_index_sequence<s>()), args...>::type;
于 2020-02-18T16:08:09.967 回答