模板元编程:如何将参数包组合成新的参数包
Template Meta Programming: How to combine parameter packs to new parameter pack
我正在尝试实现一种从元组中删除某些类型的方法;例如,我希望能够,例如,根据一个条件,只取元组的前2个模板参数中的一个元组:
- 是否可以将元组所属的类型"打包"回参数包?(元组->typename…contained_types(
- 是否可以组合一个参数。具有类型名称的包(例如,使用"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;
当我提供类型名称时
/home/juli/test.cc:6:53: error: expected ‘;’ before ‘<’ token
6 | using type = typename Helper<tpl..., curr>::take<rem-1, rest...>::type;
edit2我通过[helper函数]实现了这一点(https://gist.github.com/juliusHuelsmann/669f537aeb5e7105386d510d186b24e1),但当构造函数不是constexpr时,这些类型会在非基元类型中失败,因此我无法在用例中使用它,我很想知道如何实现这一点,以及我的方法失败的原因。
问题2的答案(是的,正如@user253751所建议的,我最初的方法(Helper<tpl..., curr>
(是正确的,但我犯了一个不同的错误,在使用的类型后面省略了"template",导致了该行中的上述错误。下面的代码显示了修复并运行良好:
#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;
相关文章:
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 模板元编程:如何将参数包组合成新的参数包
- 组合函数参数包和默认参数
- uncrustify:如何将多行 C 函数调用的参数组合到一行上?
- 如何在C++中找到可变参数类型表的所有组合
- 从组合类公开模板参数的替代方法
- 使用参数包在C++中组合 lambda 函数
- 将约束组合应用于参数包
- 组合类模板默认参数和变异参数
- 如何将多个可变参数模板元组类组合成一个类?
- 使用参数组合创建对象
- 组合模板参数形成函数签名时无效的 void 参数
- 在类组合中调用参数化构造函数
- 模板参数的组合排序
- C++组合参数模板元编程
- Boost.Parameter:与 CRTP 组合的命名模板参数
- 为什么我们不能在函数参数列表中将相同的dataype参数组合在一起?
- OpenCV iOS -不支持的参数组合
- 最佳实践是使用枚举使用按位参数组合
- 我是否需要为所有可能的输入参数组合提供构造函数?