如何从元组 C++ 中过滤重复类型

2022-01-19 00:00:00 tuples metaprogramming c++

如何过滤元组中的重复类型?

How does one filter duplicate types from a tuple?

例如:

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

其中 without_duplicates 的实现方式是生成以下 FilteredTuple 类型:

In which without_duplicates is implemented in such a way that it generates the following FilteredTuple type:

std::tuple<int, double, std::string>

推荐答案

这应该可行:

template <class Haystack, class Needle>
struct contains;

template <class Car, class... Cdr, class Needle>
struct contains<std::tuple<Car, Cdr...>, Needle> : contains<std::tuple<Cdr...>, Needle>
{};

template <class... Cdr, class Needle>
struct contains<std::tuple<Needle, Cdr...>, Needle> : std::true_type
{};

template <class Needle>
struct contains<std::tuple<>, Needle> : std::false_type
{};



template <class Out, class In>
struct filter;

template <class... Out, class InCar, class... InCdr>
struct filter<std::tuple<Out...>, std::tuple<InCar, InCdr...>>
{
  using type = typename std::conditional<
    contains<std::tuple<Out...>, InCar>::value
    , typename filter<std::tuple<Out...>, std::tuple<InCdr...>>::type
    , typename filter<std::tuple<Out..., InCar>, std::tuple<InCdr...>>::type
  >::type;
};

template <class Out>
struct filter<Out, std::tuple<>>
{
  using type = Out;
};


template <class T>
using without_duplicates = typename filter<std::tuple<>, T>::type;

[现场示例]

它通过迭代构造输出元组来工作.在添加每种类型之前,检查(使用谓词 contains)它是否已经在输出元组中.如果没有,则添加(std::conditional 的else"分支),否则不添加(std::conditional 的then"分支).

It works by iteratively constructing the output tuple. Before each type is added, check (using the predicate contains) whether it's already in the output tuple or not. If not, it's added (the "else" branch of std::conditional), otherwise it's not added (the "then" branch of std::conditional).

相关文章