使用 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/