Как фильтровать дубликаты типов из кортежа?

Например:

using Tuple = std::tuple<int, double, int, double, std::string, std::string>
using FilteredTuple = without_duplicates<Tuple>;

В котором Without_duplicates реализован таким образом, что он генерирует следующий тип FilteredTuple:

std::tuple<int, double, std::string>
13
Andreas Loanjoe 1 Май 2019 в 22:57

2 ответа

Если у вас есть доступ к Boost, это можно сделать напрямую с помощью boost::mp11::mp_unique<your_tuple_type>.

Например:

{
  using not_unique = std::tuple<int, int, char, std::string, double, int>;
  using filtered = boost::mp11::mp_unique<not_unique>;
  static_assert(std::is_same_v<std::tuple<int, char, std::string, double>, filtered>);
}
{
  using already_unique = std::tuple<int, char, std::string, double>;
  using filtered = boost::mp11::mp_unique<already_unique>;
  static_assert(std::is_same_v<std::tuple<int, char, std::string, double>, filtered>);
}

Живой пример

3
Joe 1 Июн 2019 в 20:59
#include <type_traits>
#include <tuple>

template <typename T, typename... Ts>
struct unique : std::type_identity<T> {};

template <typename... Ts, typename U, typename... Us>
struct unique<std::tuple<Ts...>, U, Us...>
    : std::conditional_t<(std::is_same_v<U, Ts> || ...)
                       , unique<std::tuple<Ts...>, Us...>
                       , unique<std::tuple<Ts..., U>, Us...>> {};

template <typename... Ts>
using unique_tuple = typename unique<std::tuple<>, Ts...>::type;

ДЕМО

3
Piotr Skotnicki 16 Авг 2019 в 16:36