要删除相邻的重复项(如std::unique),您可以这样做:
template <typename Seq, typename Res = std::index_sequence<>>
struct reverse;
template <typename Res>
struct reverse<std::index_sequence<>, Res>
{
using type = Res;
};
template <std::size_t I, std::size_t ... Is, std::size_t ... Js>
struct reverse<std::index_sequence<I, Is...>, std::index_sequence<Js...>> : reverse<std::index_sequence<Is...>, std::index_sequence<I, Js...>>
{};
template <typename Seq, typename Res = std::index_sequence<>>
struct uniq;
template <typename Res>
struct uniq<std::index_sequence<>, Res>
{
using type = typename reverse<Res>::type;
};
template <std::size_t I, std::size_t ... Is, std::size_t ... Js>
struct uniq<std::index_sequence<I, Is...>, std::index_sequence<I, Js...>> : uniq<std::index_sequence<Is...>, std::index_sequence<I, Js...>> {};
template <std::size_t I, std::size_t ... Is, std::size_t ... Js>
struct uniq<std::index_sequence<I, Is...>, std::index_sequence<Js...>> : uniq<std::index_sequence<Is...>, std::index_sequence<I, Js...>> {};
static_assert(std::is_same_v<reverse<std::index_sequence<3, 2, 1>>::type, std::index_sequence<1, 2, 3>>);
static_assert(std::is_same_v<uniq<std::index_sequence<1,2,2,2,3,3,3>>::type, std::index_sequence<1, 2, 3>>);
Demo
在 C++20 中,一些算法甚至变成了 constexpr 并允许:
template <std::size_t ... Is, std::size_t ... Js>
consteval auto unique_impl(std::index_sequence<Is...>, std::index_sequence<Js...>)
{
constexpr std::array<std::size_t, sizeof...(Is)> arr = [](){
std::array<std::size_t, sizeof...(Is)> arr{{Is...}};
//std::sort(arr.begin(), arr.end());
std::unique(arr.begin(), arr.end());
return arr;
}();
return std::index_sequence<arr[Js]...>{};
}
template <std::size_t ... Is>
consteval auto unique_impl(std::index_sequence<Is...> seq)
{
constexpr std::size_t size = [](){
std::array<std::size_t, sizeof...(Is)> arr{{Is...}};
//std::sort(arr.begin(), arr.end());
auto it = std::unique(arr.begin(), arr.end());
return std::distance(arr.begin(), it);
}();
return unique_impl(seq, std::make_index_sequence<size>());
}
template <std::size_t ... Is>
using unique = decltype(unique_impl(std::index_sequence<Is...>{}));
static_assert(std::is_same_v<unique<1,2,2,2,3,3,3>, std::index_sequence<1, 2, 3>>);
Demo
注意:constexpr std::vector 通常甚至允许删除 lambda 中的重复代码。