ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c – 比较两个类型的多重集以获得相等性

2019-08-28 14:07:02  阅读:161  来源: 互联网

标签:c c11 templates variadic-templates template-meta-programming


由于this问题似乎没有涵盖所有有用的案例,我决定填补我的这个小问题的空白.如果两个类型的多个集合相等,有没有办法回答?

#include <tuple>
#include <type_traits>

template <typename, typename>
struct type_multiset_eq : std::false_type
{
};

template <typename ... Types1, typename ... Types2>
struct type_multiset_eq<std::tuple<Types1...>, std::tuple<Types2...>>
    : std::true_type
{
    // Should only be true_type if the multisets of types are equal
};

int main() {

    static_assert(type_multiset_eq<std::tuple<char, int, double, float, int, float>, std::tuple<float, char, int, double, int, float>>::value, "err");
    static_assert(!type_multiset_eq<std::tuple<char, int, double, float, int, float>, std::tuple<char, int, double, int, float>>::value, "err");
    static_assert(type_multiset_eq<std::tuple<char, char, char, float, float, float>, std::tuple<char, float, char, float, char, float>>::value, "err");
    static_assert(!type_multiset_eq<std::tuple<int, int>, std::tuple<int, int, int>>::value, "err");
}

解决方法:

有趣的问题……

从原始问题(type_set_eq one)中的答案中获取灵感(好吧……复制它),添加一个类型计数器(countT)并删除辅助结构和标签结构,我想你可以简单地写一些如下内容

#include <tuple>
#include <type_traits>

template <typename ...>
struct countT;

template <typename T>
struct countT<T>
 { static constexpr std::size_t value { 0U }; };

template <typename T, typename T0, typename ... Ts>
struct countT<T, T0, Ts...>
 { static constexpr std::size_t value { countT<T, Ts...>::value }; };

template <typename T, typename ... Ts>
struct countT<T, T, Ts...>
 { static constexpr std::size_t value { 1U + countT<T, Ts...>::value }; };

template <bool ...>
struct bool_pack
 { };

template <bool ... Bs>
using my_and = std::is_same<bool_pack<Bs..., true>, bool_pack<true, Bs...>>;

template <typename, typename, typename = void>
struct type_multiset_eq : std::false_type
 { };

template <template <typename ...> class C1, typename ... Ts1,
          template <typename ...> class C2, typename ... Ts2>
struct type_multiset_eq<C1<Ts1...>, C2<Ts2...>,
   typename std::enable_if<
         (sizeof...(Ts1) == sizeof...(Ts2))
      && (my_and<(    countT<Ts1, Ts1...>::value
                   == countT<Ts1, Ts2...>::value)...>::value)
      >::type>
 : std::true_type
 { };

int main()
 {
   static_assert( type_multiset_eq<
      std::tuple<char, int, double, float, int, float>,
      std::tuple<float, char, int, double, int, float>>::value, "err");
   static_assert( ! type_multiset_eq<
      std::tuple<char, int, double, float, int, float>,
      std::tuple<char, int, double, int, float>>::value, "err");
   static_assert( type_multiset_eq<
      std::tuple<char, char, char, float, float, float>,
      std::tuple<char, float, char, float, char, float>>::value, "err");
   static_assert( ! type_multiset_eq<
      std::tuple<int, int>,
      std::tuple<int, int, int>>::value, "err");
 }

如果您可以使用C 14,您可以使用以下constexpr函数替换countT类型特征

template <typename T, typename ... Ts>
constexpr std::size_t cntT ()
 {
   using unused = std::size_t[];

   std::size_t  ret { 0U };

   (void)unused { 0U, ret += (std::is_same<T, Ts>::value ? 1U : 0U)... };

   return ret;
 }

标签:c,c11,templates,variadic-templates,template-meta-programming
来源: https://codeday.me/bug/20190828/1752520.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有