c++ - 部分或完全匹配类型参数包

标签 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): error C2210: '_Val': pack expansions cannot be used as arguments to non-packed parameters in alias templates

1>signal.hpp(25): note: see reference to class template instantiation 'VariadicArguments::IsSame' being compiled 1>d:\dell\source\repos\mimg\mimg-base\signal.hpp(29): note: see reference to class template instantiation 'VariadicArguments' being compiled

1>signal.hpp(25): error C3770: 'unknown-type': is not a valid base class

1>signal.hpp(25): warning C4346: 'VariadicArguments::IsSame': dependent name is not a type 1>d:\dell\source\repos\mimg\mimg-base\signal.hpp(25): note: prefix with 'typename' to indicate a type

1>signal.hpp(25): error C2143: syntax error: missing ',' before '::'

1>signal.hpp(25): error C2039: 'value': is not a member of '`global namespace''

1>signal.hpp(25): error C2143: syntax error: missing ',' before '>'

1>signal.hpp(41): error C3769: 'VariadicArguments': a nested class cannot have the same name as the immediately enclosing class

1>signal.hpp(57): error C2953: 'VariadicArguments<>::VariadicArguments': class template has already been defined

1>signal.hpp(16): note: see declaration of 'VariadicArguments<>::VariadicArguments'

1>signal.hpp(67): error C3412: 'VariadicArguments<>': cannot specialize template in current scope

最佳答案

我建议一个更简单的 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。

关于c++ - 部分或完全匹配类型参数包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51156500/

相关文章:

C++14 非聚合的统一初始化

c++ - 一个 vector/映射中的 std::function 变量参数

c++ - 更喜欢 std::swap 而不是容器的 swap()?

c++ - 如何为类声明友元函数?

c++ - 具有 `const char *` 特化的按引用传递模板函数

c++ - 标准 <memory> 文件中 boost::shared_ptr 和 std::shared_ptr 之间的区别

c++ - 通用重载运算符

c++ - 如何使用 mysql 连接器 c++ 设置 autoreconnect 选项

c++ - 在模板化容器成员上调用类函数

c++ - std::vector 上的 tbb::parallel_reduce