Templates SFINAE:检查两个可变数据包的串联是否与一个数据包相同

Templates SFINAE:检查两个可变数据包的串联是否与一个数据包相同,templates,c++14,variadic-templates,template-meta-programming,sfinae,Templates,C++14,Variadic Templates,Template Meta Programming,Sfinae,是否有方法检查两个可变参数包的串联是否与第三个可变参数包相同 template<typename... Args> struct ClassOne { } template<typename... Args> struct ClassTwo { } template<typename... Args> struct ClassThree { } template<typename... PackA, typename... PackB, typen

是否有方法检查两个可变参数包的串联是否与第三个可变参数包相同

template<typename... Args>
struct ClassOne
{
}

template<typename... Args>
struct ClassTwo
{
}

template<typename... Args>
struct ClassThree
{
}

template<typename... PackA, typename... PackB, typename... PackC>
void foo(ClassOne<PackA...>, ClassTwo<PackB...>, ClassThree<PackC...>)
{
}
模板
结构类一
{
}
模板
结构类二
{
}
模板
结构类三
{
}
模板
void foo(一级、二级、三级)
{
}

我希望只有当PackA…=PackB…,PackC…

首先,创建一个
pack
类来存储一组类型:

template <typename... Ts> struct pack { };
模板结构包{};
然后,编写一个函数来检查两个包是否相同:

template <typename P0, typename P1>
struct are_packs_same;

template <typename... T0s, typename... T1s>
struct are_packs_same<pack<T0s...>, pack<T1s...>>
    : std::bool_constant<(sizeof...(T0s) == sizeof...(T1s)) 
                      && (std::is_same_v<T0s, T1s> && ...)>
{
};
模板
结构是相同的;
模板
结构包是否相同
:std::bool_常数
{
};
最后,您需要一个函数来连接两个包:

template <typename P0, typename P1>
struct concat_packs;

template <typename... T0s, typename... T1s>
struct concat_packs<pack<T0s...>, pack<T1s...>>
{
    using type = pack<T0s..., T1s...>;
};
模板
结构concat_包;
模板
结构concat_包
{
使用类型=包装;
};
用法示例:

int main()
{
    using p0 = pack<int, char>;
    using p1 = pack<float>;
    using p2 = pack<int, char, float>;

    static_assert(are_packs_same<
        typename concat_packs<p0, p1>::type,
        p2>::value);
}
intmain()
{
使用p0=包装;
使用p1=包装;
使用p2=包装;
静态断言(包是否相同<
typename concat_packs::type,
p2>::值);
}

相当简单

template <typename ...>
struct pack{};

template<typename... PackA, typename... PackB, typename... PackC,
  typename = typename std::enable_if
     <std::is_same<pack<PackA...>, 
                   pack<PackB..., PackC...>>::value
     >::type>
void foo(ClassOne<PackA...>, ClassTwo<PackB...>, ClassThree<PackC...>)
{
}
模板
结构包{};
模板
void foo(一级、二级、三级)
{
}
模板结构类型{
friend constexpr std::true_type运算符==(类型,类型){return{};}
模板
friend constexpr std::false_type操作符==(类型,类型){return{};}
constexpr类型(){}
模板
friend constexpr自动运算符!=(类型self,类型ts)
->积分常数
{返回{};}
};
templateconstexpr类型包{};
现在:

模板
std::如果启用,则启用
foo(一类,二类,三类){}
读起来像英语

或者:

template<class...> struct types{
  friend constexpr bool operator==(types,types) { return true; }
  template<class...Ts>
  friend constexpr bool operator==(types,types<Ts...>) { return false; }
  constexpr types(){}
  template<class...Ts>
  friend constexpr bool operator!=(types self, types<Ts...> ts )
  { return !(self==ts); }
};
模板结构类型{
friend constexpr bool运算符==(类型,类型){return true;}
模板
friend constexpr bool运算符==(类型,类型){return false;}
constexpr类型(){}
模板
friend constexpr bool运算符!=(类型self,类型ts)
{return!(self==ts);}
};

它稍微简单一点,工作原理也很相似。

可能重复我想比较参数包的串联,但我忘了提到类是不相关的,很抱歉更新了它。你怎么能不在包上写constexpr==呢。我的意思是道德上的。哦,很好,我可以用它来扩展我的type_list类:)谢谢。我真的不明白line->std::integral_常量如何在std integral常量表达式中使用函数参数?这些不是运行时参数吗?@andr抱歉,缺少一个decltype,并且有一些早期版本的额外常量,我刚刚返回了一个
constexpr bool
template<typename... PackA, typename... PackB, typename... PackC>
std::enable_if_t<pack<PackA...> ==pack<PackB...> && pack<PackB...> ==pack<PackC...>>
foo(ClassOne<PackA...>, ClassTwo<PackB...>, ClassThree<PackC...>) { }
template<class...> struct types{
  friend constexpr bool operator==(types,types) { return true; }
  template<class...Ts>
  friend constexpr bool operator==(types,types<Ts...>) { return false; }
  constexpr types(){}
  template<class...Ts>
  friend constexpr bool operator!=(types self, types<Ts...> ts )
  { return !(self==ts); }
};