代码之家  ›  专栏  ›  技术社区  ›  Chen Li

当foo是一个接受单个模板参数的结构时,`foo<Type1,Types…>`合法吗?

  •  3
  • Chen Li  · 技术社区  · 7 年前

    在玩libstdcxx时 test_property :

    template<template<typename...> class Property,
           typename Type1, typename... Types>
    constexpr bool
    test_property(typename Property<Type1, Types...>::value_type value)
    {
        return (Property<Type1, Types...>::value == value
          && Property<Type1, Types...>::type::value == value);
     }
    

    class Property 至少接受一个模板参数( Type1

    Here 是一个用例:

    static_assert(test_property<is_copy_assignable, ExceptMoveAssignClass>(false), "");
    

    但我发现clang不能很好地使用此函数:

    prog.cc:29:3: error: no matching function for call to 'test_property'
                    test_property<std::is_copy_assignable, DeletedMoveAssignClass>(false);
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    prog.cc:12:1: note: candidate template ignored: substitution failure [with Property = std::is_copy_assignable, Type1 = DeletedMoveAssignClass]: too many template arguments for class template 'is_copy_assignable'
    test_property(typename Property<Type1, Types...>::value_type value)
    ^                      ~~~~~~~~
    1 error generated.
    

    根本原因是叮当声不允许 类属性 template< class T > struct is_copy_assignable; . 一旦 类属性 修改为 Property<Type1>

    template<template<typename...> class Property, typename Type1>
    constexpr bool
    ya_test_property(typename Property<Type1>::value_type value)
    {
        return (Property<Type1>::value == value
            && Property<Type1>::type::value == value);
    }
    

    这是演示 https://wandbox.org/permlink/LlL1o57Yted5WZo5

    当然,这个函数来自libstdcxx, so gcc can pass compile

    1 回复  |  直到 7 年前
        1
  •  3
  •   StoryTeller - Unslander Monica    7 年前

    如果我在解释的话,看起来像个叮当作响的虫子 [temp.variadic]/7 正确地:

    列表这样的实例化不会改变语法结构 对封闭结构的解释,即使在 如果完全忽略该列表,则会导致格式错误或 :

    template<class... T> struct X : T... { };
    template<class... T> void f(T... values) {
      X<T...> x(values...);
    }
    
    template void f<>();    // OK: X<> has no base classes
                            // x is a variable of type X<> that is value-initialized
    

    [结束示例]

    同样地 std::is_copy_assignable<ExceptMoveAssignClass , > 这是不正确的,一个空包不应该让我们处于这种状态。它应该相当于 std::is_copy_assignable<ExceptMoveAssignClass>

    不是吗 是

    推荐文章