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.