|| 的无关可见重载防止 ||从要求条款中短路
Unrelated visible overload of || prevents || from short-circuiting in a requires-clause
Cppreference 说:
Disjunctions are evaluated left to right and short-circuited (if the left constraint is satisfied, template argument substitution into the right constraint is not attempted).
这似乎是正确的,因为可以编译以下代码:
template <typename T>
struct A
{
static constexpr bool value = T::value;
};
template <typename T>
void foo() requires (sizeof(T) == 1) || A<T>::value {}
int main()
{
foo<char>();
}
即使 A<char>::value
格式错误,也没有错误,因为它被短路了。
但是如果我添加一个不相关的 operator||
重载,它就会停止工作:
struct Dummy {};
bool operator||(Dummy, Dummy) {return true;}
template <typename T>
struct A
{
static constexpr bool value = T::value;
};
template <typename T>
void foo() requires (sizeof(T) == 1) || A<T>::value {}
int main()
{
foo<char>();
}
现在 Clang (10.0.0) 开始抱怨:
<source>:7:35: error: type 'char' cannot be used prior to '::' because it has no members
static constexpr bool value = T::value;
^
<source>:11:47: note: in instantiation of static data member 'A<char>::value' requested here
void foo() requires (sizeof(T) == 1) || A<T>::value {}
^
<source>:11:21: note: while substituting template arguments into constraint expression here
void foo() requires (sizeof(T) == 1) || A<T>::value {}
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:15:5: note: while checking constraint satisfaction for template 'foo<char>' required here
foo<char>();
^~~
<source>:15:5: note: in instantiation of function template specialization 'foo<char>' requested here
GCC (trunk) 对此代码没有问题。
如果 operator||
位于命名空间中(并且没有 using namespace
),则代码有效。
这是一个 Clang 错误吗?除了没有 ||
?
的可见重载之外,是否有任何解决方法
这个错误 was fixed,因此短路将在 Clang 11 中正常工作。
Cppreference 说:
Disjunctions are evaluated left to right and short-circuited (if the left constraint is satisfied, template argument substitution into the right constraint is not attempted).
这似乎是正确的,因为可以编译以下代码:
template <typename T>
struct A
{
static constexpr bool value = T::value;
};
template <typename T>
void foo() requires (sizeof(T) == 1) || A<T>::value {}
int main()
{
foo<char>();
}
即使 A<char>::value
格式错误,也没有错误,因为它被短路了。
但是如果我添加一个不相关的 operator||
重载,它就会停止工作:
struct Dummy {};
bool operator||(Dummy, Dummy) {return true;}
template <typename T>
struct A
{
static constexpr bool value = T::value;
};
template <typename T>
void foo() requires (sizeof(T) == 1) || A<T>::value {}
int main()
{
foo<char>();
}
现在 Clang (10.0.0) 开始抱怨:
<source>:7:35: error: type 'char' cannot be used prior to '::' because it has no members
static constexpr bool value = T::value;
^
<source>:11:47: note: in instantiation of static data member 'A<char>::value' requested here
void foo() requires (sizeof(T) == 1) || A<T>::value {}
^
<source>:11:21: note: while substituting template arguments into constraint expression here
void foo() requires (sizeof(T) == 1) || A<T>::value {}
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:15:5: note: while checking constraint satisfaction for template 'foo<char>' required here
foo<char>();
^~~
<source>:15:5: note: in instantiation of function template specialization 'foo<char>' requested here
GCC (trunk) 对此代码没有问题。
如果 operator||
位于命名空间中(并且没有 using namespace
),则代码有效。
这是一个 Clang 错误吗?除了没有 ||
?
这个错误 was fixed,因此短路将在 Clang 11 中正常工作。