4

有没有办法检查两个可变参数包的连接是否与第三个可变参数包相同。SFINAE:检查两个可变参数包的连接是否与一个包相同

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...>) 
{ 
} 

我想富,只启用如果帕茨卡... = PackB ...,PackC ...

+0

[检查两个可变参数派生类是否使用相同的参数包实例化](https://stackoverflow.com/questions/37435575/check-if-two-variadic-derived-classes-are-instantiated- with-the-same-parameter-p) – Rakete1111

+0

虽然我正在比较参数包的连接,但我忘记提及类是无关的,不好意思更新它。 –

回答

4

相当简单...

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...>) 
{ 
} 
+0

当然!谢谢 –

1

首先,创建一个类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> && ...)> 
{ 
}; 

最后,你需要一个函数连接两个包:

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...>; 
}; 

用法示例:

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); 
} 

live wandbox example

+0

你怎么能不写包装上的constexpr ==。我的意思是道德上的。 – Yakk

1
template<class...> struct types{ 
    friend constexpr std::true_type operator==(types,types) { return {}; } 
    template<class...Ts> 
    friend constexpr std::false_type operator==(types,types<Ts...>) { return {}; } 
    constexpr types(){} 
    template<class...Ts> 
    friend constexpr auto operator!=(types self, types<Ts...> ts) 
    ->std::integral_constant<bool, !decltype(self == ts){}> 
    { return{}; } 
}; 
template<class...Ts>constexpr types<Ts...> pack{}; 

现在:

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); } 
}; 

这是稍微简单,工作方式类似。

+0

哦,非常好,我可以用这个扩展我的type_list类:)谢谢。 –

+0

我真的不明白这一行 - > std :: integral_constant 函数参数如何被允许在std整型常量表达式中使用?这些运行时参数不是吗? –

+0

@andr对不起,我错过了一个decltype,并且在一个更简单的版本中有一些额外的const,我刚刚返回了一个'constexpr bool'。 – Yakk

相关问题