删除模板参数包的最后一种类型
Remove the last type of a template parameter pack
我想使用模板参数包的类型作为另一个模板的参数,但要切断最后一个参数。
例如:template <class... Ts> struct some_template;
template <class... Ts> struct foo
{
using bar = some_template<magically_get_all_but_last(Ts)...>;
};
// I might be missing a few "typename"s, but you get the idea.
static_assert(std::is_same<foo<int, bool, std::string>::bar, some_template<int,bool> >::value);
注意,这与只获取最后一个参数相反。
这里是一个简单的方法,使用std::tuple_element<I, Tuple>
和std::index_sequence<sizeof...(Ts) - 1
来获得可变参数列表中除最后一个类型外的所有类型。因为需要索引的参数包,所以有一个额外的间接,它可以放在基中,但可以放在任何地方。
template <class T, class... Ts> struct foobase;
template <std::size_t... I, class... Ts>
struct foobase<std::index_sequence<I...>, Ts...> {
using bar = some_template<typename std::tuple_element<I, std::tuple<Ts...>>::type...>;
};
template <class... Ts> struct foo
: foobase<std::make_index_sequence<sizeof...(Ts) - 1>, Ts...>
{
};
下面是我使用c++ 11的解决方案:
template <typename ...P>
struct dummy {};
template <template <typename ...> class Obj, typename T, typename ...P>
struct internal;
template <template <typename ...> class Obj, typename ...P1, typename T, typename ...P2>
struct internal<Obj, dummy<P1...>, T, P2...>
{
using type = typename internal<Obj, dummy<P1..., T>, P2...>::type;
};
template <template <typename ...> class Obj, typename ...P1, typename T, typename L>
struct internal<Obj, dummy<P1...>, T, L>
{
using type = Obj<P1..., T>;
};
template <template <typename ...> class T, typename ...P>
struct subst_all_but_last
{
using type = typename internal<T, dummy<>, P...>::type;
};
像这样使用:
using bar = typename subst_all_but_last<some_template, Ts...>::type;
不是using bar = some_template<magically_get_all_but_last(Ts)...>;
这似乎可以工作:
#include <tuple>
#include <utility>
#include <cstdint>
using std::size_t;
using std::tuple;
namespace
{
template <class Tuple, template <class...> class Template> struct apply_tuple_params_impl {};
template <template <class...> class Template, class... Params>
struct apply_tuple_params_impl<tuple<Params...>, Template>
{
typedef Template<Params...> type;
};
template <class Param, class Tuple> struct extend_tuple;
template <class Param, class... Params> struct extend_tuple<Param, tuple<Params...>>
{
typedef tuple<Param, Params...> type;
};
template <class Param, class... Params> struct all_but_last_type_tuple_impl
{
typedef typename extend_tuple<Param, typename all_but_last_type_tuple_impl<Params...>::type>::type type;
};
template <class Param> struct all_but_last_type_tuple_impl<Param>
{
typedef tuple<> type;
};
}
// pass the template parameters of a tuple to another template
template <class Tuple, template <class...> class Template>
using apply_tuple_params = typename apply_tuple_params_impl<Tuple, Template>::type;
// a tuple type with all the parameters except the last
template <class... Params>
using all_but_last_type_tuple = typename all_but_last_type_tuple_impl<Params...>::type;
并像这样使用:
template <class... Ts> struct some_template;
template <class... Ts> struct foo
{
typedef apply_tuple_params<all_but_last_type_tuple<Ts...>, some_template> bar;
};
static_assert(std::is_same<foo<int, bool, std::string>::bar, some_template<int,bool> >::value, "");
相关文章:
- 在运行时检查继承是否只有一种类型和 void*
- 另一种类型的智能ptr,比如具有弱refs的unique_ptr
- void* 数组将元素转换为另一种类型
- 将一种类型的比特重新解释为不同类型的比特的技术
- 为什么需要类型名称,即使似乎足以推断名称应该是一种类型?
- 在 c++ 中将一种结构类型分配给另一种类型
- 将空基类优化对象强制转换为另一种类型是否会破坏严格的别名?
- 我怎样才能让编译器推导出一种类型的 nullptr
- 一种类型的多个 cv 分解
- 如何将对象定义为一种类型,然后再将其声明为子类型
- 类中的结构不是一种类型
- 一种类型特征,标识哪个类提供通过重载解析选择的函数
- 将 32 位浮点数和不强制转换的 32 位整数与双精度进行比较,当其中一个值可能太大而无法完全适合另一种类型时
- constexpr检查一种类型
- 何时与另一种类型兼容
- 依赖名称不是一种类型,带有 SFINAE 的模板
- 自动将一种 c++ 类型转换为另一种
- C 模板可以匹配(仅)一种类型的列表或另一种类型的列表
- 是否可以将一种类型的数组转换为大小不同的另一种类型的数组?
- 在比较中使用已强制转换为另一种类型的函数指针是否定义良好?