Несвязанная видимая перегрузка || предотвращает || от короткого замыкания в требовании - PullRequest
4 голосов
/ 17 апреля 2020

Cppreference говорит:

Различия оцениваются слева направо и замыкаются накоротко (если выполняется левое ограничение, замена аргумента шаблона в правое ограничение не предпринимается) ,

Кажется, это правильно, потому что компилируется следующий код:

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

Запуск на g cc .godbolt.org

Теперь 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

G CC (trunk) не имеет проблем с этим кодом.

Если operator|| находится в пространстве имен (и нет using namespace), код работает.

Это ошибка Clang? Есть ли обходные пути, кроме отсутствия видимых перегрузок ||?

...