匹配部分或全部类型的参数包

时间:2018-07-03 13:59:16

标签: c++ c++11 c++14 variadic-templates c++17

我想检查类型参数包是否与另一个参数包部分或完全匹配。

到目前为止,我正在尝试:

template<typename... Arguments>
struct VariadicArguments
{
    template<typename... AnotherArguments>
    struct IsSame: std::bool_constant<sizeof...(AnotherArguments)==0> {};
};

template<typename Arg, typename... Arguments>
struct VariadicArguments<Arg, Arguments...>
{
    template<typename... Args>
    struct IsSame: std::false_type{};

    template<typename AnotherArg, typename... AnotherArguments>
    struct IsSame<AnotherArg, AnotherArguments...>:
        std::bool_constant<
            std::is_same<Arg, AnotherArg>::value &&
            VariadicArguments<Arguments...>::IsSame<AnotherArguments...>::value> { };

    template<>
    struct IsSame<> : std::true_type{};
};

template<>
struct VariadicArguments<>
{
    template<typename... Args>
    struct IsSame : std::false_type {};

    template<>
    struct IsSame<> : std::true_type {};
};

我预测到

VariadicArguments<int, float, double>::IsSame<int, float>::value // true because (int, float, double) partially matches (int, float)
VariadicArguments<int, float, double>::IsSame<int, double>::value // false because (int, float, double) doesn't partially matches (int, double) it should be in serial
VariadicArguments<int, float, double>::IsSame<int, float, double>::value // true because they are all same in serial
VariadicArguments<int, float, double>::IsSame<>::value // true because no arguments matches every parameter pack.

但是我遇到了一些编译时错误

  

1> signal.hpp(25):错误C2210:   '_Val':打包扩展不能用作非打包的参数   别名模板中的参数

     

1> signal.hpp(25):注意:请参见   引用类模板实例化   'VariadicArguments :: IsSame'   正在编译1> d:\ dell \ source \ repos \ mimg \ mimg-base \ signal.hpp(29):   注意:请参阅对类模板实例化的参考   正在编译“ VariadicArguments”

     

1> signal.hpp(25):错误C3770:   'unknown-type':不是有效的基类

     

1> signal.hpp(25):警告C4346:   'VariadicArguments :: IsSame':从属名称不是   类型1> d:\ dell \ source \ repos \ mimg \ mimg-base \ signal.hpp(25):注意:   带有“ typename”的前缀以指示类型

     

1> signal.hpp(25):错误C2143:   语法错误:在'::'之前缺少','

     

1> signal.hpp(25):错误C2039:   'value':不是'`global namespace'的成员

     

1> signal.hpp(25):错误C2143:   语法错误:在'>'之前缺少','

     

1> signal.hpp(41):错误C3769:   'VariadicArguments':嵌套类的名称不能与   立即封闭类

     

1> signal.hpp(57):错误C2953:   'VariadicArguments <> :: VariadicArguments':类   模板已经定义

     

1> signal.hpp(16):注意:请参见   声明   'VariadicArguments <> :: VariadicArguments'

     

1> signal.hpp(67):错误C3412:   'VariadicArguments <>':无法在当前范围内专门化模板

1 个答案:

答案 0 :(得分:1)

我建议使用一个更简单的VariadicArguments(将其重命名为VarArgs,以使其更短)

template <typename...>
struct VarArgs;

template <typename A0, typename ... As>
struct VarArgs<A0, As...>
 {
   template <typename ... Bs>
   struct IsSame  : std::integral_constant<bool, sizeof...(Bs)==0>
    { };

   template <typename ... Bs>
   struct IsSame<A0, Bs...> : VarArgs<As...>::template IsSame<Bs...>
    { };
 };

template <>
struct VarArgs<>
 {
   template <typename ... Bs>
   struct IsSame : std::integral_constant<bool, sizeof...(Bs)==0>
    { };
 };

现在您可以写

int main ()
 {
   using ifd = VarArgs<int, float, double>;

   static_assert(  true == ifd::IsSame<int, float>::value, "1!" );
   static_assert( false == ifd::IsSame<int, double>::value, "2!" );
   static_assert(  true == ifd::IsSame<int, float, double>::value, "3!" );
   static_assert(  true == ifd::IsSame<>::value, "4!" );
 }

请注意,使用std::integral_constant<bool, BoolValue>而不是std::bool_constant<BoolValue>,此解决方案也适用于C ++ 11和C ++ 14,不仅适用于C ++ 17。