简体   繁体   English

|| 的无关可见过载防止|| 从要求子句中的短路

[英]Unrelated visible overload of || prevents || from short-circuiting in a requires-clause

Cppreference says: 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).析取从左到右求值并短路(如果满足左约束,则不尝试将模板参数替换为右约束)。

This appears to be correct, because following code compiles:这似乎是正确的,因为下面的代码编译:

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>();
}

Even though A<char>::value is ill-formed, there's no error because it's short-circuited away.即使A<char>::value格式错误,也没有错误,因为它被短路了。

But if I add an unrelated overload of operator||但是如果我添加一个不相关的operator|| , it stops working: ,它停止工作:

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>();
}

Run on gcc.godbolt.org 在 gcc.godbolt.org 上运行

Now Clang (10.0.0) starts to complain:现在 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) has no problem with this code. GCC(主干)这个代码没有问题。

If operator||如果operator|| is in a namespace (and there's no using namespace ), the code works.在命名空间中(并且没有using namespace ),代码有效。

Is it a Clang bug?它是 Clang 错误吗? Are there any workarounds, other than not having visible overloads of ||是否有任何解决方法,除了没有可见的||重载? ?

This bug was fixed , so the short-circuiting will work properly in Clang 11.此错误已修复,因此短路将在 Clang 11 中正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM