临时约束要求要求要求要求要求?
Ad-hoc constraint requires requires requires requires?
假设我正在编写一个 class 模板,其中一些成员受限于类型模板参数静态 constexpr 数据成员的存在 和值 :
template<class T>
struct A {
constexpr bool operator()() requires T::value { return T::value; }
constexpr bool operator()() { return false; }
};
#include <type_traits>
static_assert(A<std::true_type>()());
static_assert(!A<std::false_type>()());
static_assert(!A<void>()());
MSVC 和 gcc 接受这个,但 clang 拒绝,除非我 replace requires T::value
和 requires requires { requires T::value; }
。这是 clang 中的错误,还是其他编译器松懈? C++ 是否需要 requires requires requires requires?标准怎么说?
相关(嗯,至少⅔):
这是一个 clang 错误(已提交 #49513)。
看起来 clang 正在将 void
代入 T::value
并决定因为这是一个无效的表达式,所以约束是 无效的 。但是 [temp.constr.atomic] 中的规则是:
To determine if an atomic constraint is satisfied, the parameter mapping and template arguments are first substituted into its expression. If substitution results in an invalid type or expression, the constraint is not satisfied.
在这种情况下,替换会导致无效类型或表达式,因此结果应该是不满足约束。
注意这个重载:
constexpr bool operator()() requires T::value { return T::value; }
仅在 T::value
是有效表达式 且 计算结果为 true
时才有效。这使得它等同于:
constexpr bool operator()() requires T::value { return true; }
在这种情况下没问题,因为无论如何在另一种情况下您都会返回 false
,因此没有理由区分 T::value
存在但 false
与 T::value
不存在。
但认为无论如何都值得澄清。
假设我正在编写一个 class 模板,其中一些成员受限于类型模板参数静态 constexpr 数据成员的存在 和值 :
template<class T>
struct A {
constexpr bool operator()() requires T::value { return T::value; }
constexpr bool operator()() { return false; }
};
#include <type_traits>
static_assert(A<std::true_type>()());
static_assert(!A<std::false_type>()());
static_assert(!A<void>()());
MSVC 和 gcc 接受这个,但 clang 拒绝,除非我 replace requires T::value
和 requires requires { requires T::value; }
。这是 clang 中的错误,还是其他编译器松懈? C++ 是否需要 requires requires requires requires?标准怎么说?
相关(嗯,至少⅔):
这是一个 clang 错误(已提交 #49513)。
看起来 clang 正在将 void
代入 T::value
并决定因为这是一个无效的表达式,所以约束是 无效的 。但是 [temp.constr.atomic] 中的规则是:
To determine if an atomic constraint is satisfied, the parameter mapping and template arguments are first substituted into its expression. If substitution results in an invalid type or expression, the constraint is not satisfied.
在这种情况下,替换会导致无效类型或表达式,因此结果应该是不满足约束。
注意这个重载:
constexpr bool operator()() requires T::value { return T::value; }
仅在 T::value
是有效表达式 且 计算结果为 true
时才有效。这使得它等同于:
constexpr bool operator()() requires T::value { return true; }
在这种情况下没问题,因为无论如何在另一种情况下您都会返回 false
,因此没有理由区分 T::value
存在但 false
与 T::value
不存在。
但认为无论如何都值得澄清。