https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110160

            Bug ID: 110160
           Summary: g++ rejects concept as cyclical with non-matching
                    function signature
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: danakj at orodu dot net
  Target Milestone: ---

Godbolt: https://godbolt.org/z/d4PhfMqvq

Code:
```
#include <sstream>
#include <string>

template <class T>
concept StreamCanReceiveString = requires(T& t, std::string s) {
    { t << s };
};

struct NotAStream {};
struct UnrelatedType {};

template <StreamCanReceiveString S>
S& operator<<(S& s, UnrelatedType) {
    return s;
}

static_assert(!StreamCanReceiveString<NotAStream>);

static_assert(StreamCanReceiveString<std::stringstream>);
```

What happens here is GCC fails to be able to resolve the expression
`StreamCanReceiveString<NotAStream>`.

1. StreamCanReceiveString<NotAStream> tries to do NotAStream << std::string.
2. There is a templated operator<< that takes `StreamCanReceiveString` and
`UnrelatedType`
3. Since `UnrelatedType` is not std::string, this is not an overload candidate.
4. Clang and MSVC therefore do not try to recursively solve
`StreamCanReceiveString<NotAStream>` and reject the code. But GCC tries to
solve the concept and then fails due to recursion.

Reply via email to