[英]Check if one set of types is subsets with composition
我必須檢查給定的兩個元組是否是另一個的子集。 我找到了這種優雅的解決方案。 檢查一種類型是否是另一種類型的子集 。
但是此解決方案的問題在於它不考慮例如子類型
using t1 = std::tuple<int, double>;
using t2 = std::tuple<double, int>;
using t3 = std::tuple<t1, t2>;
這會使子集測試失敗。
#include <tuple>
#include <type_traits>
template <typename T, typename... Ts>
constexpr bool contains = (std::is_same<T, Ts>{} || ...);
template <typename Subset, typename Set>
constexpr bool is_subset_of = false;
template <typename... Ts, typename... Us>
constexpr bool is_subset_of<std::tuple<Ts...>, std::tuple<Us...>>
= (contains<Ts, Us...> && ...);
原因是,如果我們在t1和t3上做子集,則contains表達式會將int與t1進行比較,否則將失敗。 因此,所需的更改是用於包含功能以搜索子類型。
PS此代碼僅適用於C ++ 17
如果您對元組嵌套的結構不感興趣,則可以“拼合”嵌套的元組。 這意味着
int main() {
using t1 = std::tuple<int, double>;
using t2 = std::tuple<double, int>;
using t3 = std::tuple<t1, t2>;
static_assert(
std::is_same<
flatten<t3>,
std::tuple<int, double, double, int>
>{}
);
static_assert(false == is_subset_of<t1, t3>);
static_assert(true == is_subset_of< t1, flatten<t3> >);
return 0;
}
flatten
快速而骯臟的實現可能如下所示。
namespace detail {
template<class... Ts>
struct flatten {
static_assert(sizeof...(Ts) == 0, "recursion break (see specializations)");
template<class... Result>// flattened types are accumulated in this pack
using type = std::tuple<Result...>;
};
template<template<class...> class Nester, class... Nested, class... Ts>
struct flatten<Nester<Nested...>, Ts...> {// if first arg is nested then unpack
template<class... Result>
using type = typename flatten<Nested..., Ts...>::template type<Result...>;
};
template<class T0, class... Ts>
struct flatten<T0, Ts...> {// if `T0` is flat then just append it to `Result...`
template<class... Result>
using type = typename flatten<Ts...>::template type<Result..., T0>;
};
};// detail
template<class... Ts>
using flatten = typename detail::flatten<Ts...>::template type<>;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.