And*_*joe 7 c++ tuples metaprogramming
How does one filter duplicate types from a tuple?
For example:
using Tuple = std::tuple<int, double, int, double, std::string, std::string>
using FilteredTuple = without_duplicates<Tuple>;
Run Code Online (Sandbox Code Playgroud)
In which without_duplicates is implemented in such a way that it generates the following FilteredTuple type:
std::tuple<int, double, std::string>
Run Code Online (Sandbox Code Playgroud)
#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;
Run Code Online (Sandbox Code Playgroud)
这项应有的工作:
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;
Run Code Online (Sandbox Code Playgroud)
它通过迭代构造输出元组来工作。在添加每种类型之前,请检查(使用谓词contains)它是否已经在输出元组中。如果没有,则添加(的“ else”分支std::conditional),否则不添加(的“ then”分支std::conditional)。