c++ - 当 foo 是接受单个模板参数的结构时, `foo<Type1, Types...>` 是否合法?

标签 c++ templates clang libstdc++ compiler-bug

使用 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接受至少 1 个模板参数 ( 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.

根本原因是 clang 不允许 class Property成为只接受一个模板参数的类,如 template< class T > struct is_copy_assignable; .一次class Property修改为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 .这是clang的错误吗?

最佳答案

如果我正在解释 [temp.variadic]/7,这看起来像是一个 Clang 错误正确:

When N is zero, the instantiation of the expansion produces an empty list. Such an instantiation does not alter the syntactic interpretation of the enclosing construct, even in cases where omitting the list entirely would otherwise be ill-formed or would result in an ambiguity in the grammar. [ Example:

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

 — end example ]

类似地,虽然 std::is_copy_assignable<ExceptMoveAssignClass , >格式错误,空包不应该让我们处于这种状态。它应该等同于 std::is_copy_assignable<ExceptMoveAssignClass> , 这是良构的。

当然,如果包不是为空,那么我们将传递太多参数, 格式错误。但事实并非如此。

关于c++ - 当 foo 是接受单个模板参数的结构时, `foo<Type1, Types...>` 是否合法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54301862/

相关文章:

c++ - 生成径向梯度的算法

c++ - 检查模板参数是否具有随机访问迭代器

c++ - 对 "non-type"模板参数执行规则

使用 clang 的 C++ 模块

XCode 4.6 clang 分析器担心空 C++ 指针不能为空

c++ - 如果我有角度和轴,如何在 PCL 中进行旋转平移?

c++ - 正则表达式从大括号构建 vector

c++ - 以二进制形式打印文件

c++ - 基于模板参数是否为 shared_ptr 的函数特化

c++ - 尽管包含 <typeinfo> ,但 Clang 拒绝 type_info 为不完整