csc*_*wan 24 c++ c++11 stdtuple
这似乎是一个非常简单的问题:如何删除第一个(第n个)类型std::tuple?
例:
typedef std::tuple<int, short, double> tuple1;
typedef std::tuple<short, double> tuple2;
Run Code Online (Sandbox Code Playgroud)
上述操作将转变tuple1为tuple2.可能吗?
And*_*owl 28
您可以使用基于类模板的部分特化的简单类型函数:
#include <type_traits>
#include <tuple>
using namespace std;
template<typename T>
struct remove_first_type
{
};
template<typename T, typename... Ts>
struct remove_first_type<tuple<T, Ts...>>
{
typedef tuple<Ts...> type;
};
int main()
{
typedef tuple<int, bool, double> my_tuple;
typedef remove_first_type<my_tuple>::type my_tuple_wo_first_type;
static_assert(
is_same<my_tuple_wo_first_type, tuple<bool, double>>::value,
"Error!"
);
}
Run Code Online (Sandbox Code Playgroud)
此外,这个解决方案可以很容易地推广到删除第i类元组:
#include <type_traits>
#include <tuple>
using namespace std;
template<size_t I, typename T>
struct remove_ith_type
{
};
template<typename T, typename... Ts>
struct remove_ith_type<0, tuple<T, Ts...>>
{
typedef tuple<Ts...> type;
};
template<size_t I, typename T, typename... Ts>
struct remove_ith_type<I, tuple<T, Ts...>>
{
typedef decltype(
tuple_cat(
declval<tuple<T>>(),
declval<typename remove_ith_type<I - 1, tuple<Ts...>>::type>()
)
) type;
};
int main()
{
typedef tuple<int, bool, double> my_tuple;
typedef remove_ith_type<1, my_tuple>::type my_tuple_wo_2nd_type;
static_assert(
is_same<my_tuple_wo_2nd_type, tuple<int, double>>::value,
"Error!"
);
}
Run Code Online (Sandbox Code Playgroud)
我写了一个被C++ 14标准接受的提议,这使得它很容易为任何"类似元组"的类型做,即支持tuple_size和tuple_elementAPI的类型:
template<typename T, typename Seq>
struct tuple_cdr_impl;
template<typename T, std::size_t I0, std::size_t... I>
struct tuple_cdr_impl<T, std::index_sequence<I0, I...>>
{
using type = std::tuple<typename std::tuple_element<I, T>::type...>;
};
template<typename T>
struct tuple_cdr
: tuple_cdr_impl<T, std::make_index_sequence<std::tuple_size<T>::value>>
{ };
Run Code Online (Sandbox Code Playgroud)
并且您可以使用几个函数将元组对象转换为新类型:
template<typename T, std::size_t I0, std::size_t... I>
typename tuple_cdr<typename std::remove_reference<T>::type>::type
cdr_impl(T&& t, std::index_sequence<I0, I...>)
{
return std::make_tuple(std::get<I>(t)...);
}
template<typename T>
typename tuple_cdr<typename std::remove_reference<T>::type>::type
cdr(T&& t)
{
return cdr_impl(std::forward<T>(t),
std::make_index_sequence<std::tuple_size<T>::value>{});
}
Run Code Online (Sandbox Code Playgroud)
这将创建一个整数序列[0,1,2,...,N),其中N是tuple_size<T>::value,然后创建一个新的元组make_tuple(get<I>(t)...)用于I在[1,2,...,N)
测试它:
using tuple1 = std::tuple<int, short, double>;
using tuple2 = std::tuple<short, double>;
using transformed = decltype(cdr(std::declval<tuple1>()));
static_assert(std::is_same<transformed, tuple2>::value, "");
static_assert(std::is_same<tuple_cdr<tuple1>::type, tuple2>::value, "");
#include <iostream>
int main()
{
auto t = cdr(std::make_tuple(nullptr, "hello", "world"));
std::cout << std::get<0>(t) << ", " << std::get<1>(t) << '\n';
}
Run Code Online (Sandbox Code Playgroud)
我对该提案的参考实现位于https://gitlab.com/redistd/integer_seq/blob/master/integer_seq.h
| 归档时间: |
|
| 查看次数: |
4846 次 |
| 最近记录: |