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

--- Comment #2 from Johel Ernesto Guerrero Peña <johelegp at gmail dot com> ---
FWIW, it seems that you can use
<https://quuxplusone.github.io/blog/2022/01/04/test-constexpr-friendliness/>
to test the validity during constant evaluation.
It seems that an invalid constant expression implies a `false` result.
So I guard the check with a validity check:
<https://compiler-explorer.com/z/had59d6nv>.

```C++
#include <type_traits>
template<auto F> concept is_constant = requires { typename
std::integral_constant<int, (F(), 0)>; };
template<auto l, auto r>
constexpr bool implements() {
  using R = decltype(r);
  if constexpr (requires { static_cast<R>(l); })
#if !defined(__GNUC__) || defined(__clang__)
    return static_cast<R>(l) != r;
#else // Workaround <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71962>.
    return !is_constant<[]() { return static_cast<R>(l) != r; }> ||
static_cast<R>(l) != r;
#endif
  return false;
}
struct B { void f(); };
struct D0 : B { };
struct D1 : B { void f(); };
struct D2 : B { void f() const; };
// struct D3 : B { int f(); void f() const; };
static_assert(!implements<&D0::f, &B::f>());
static_assert(implements<&D1::f, &B::f>());
static_assert(!implements<&D2::f, &B::f>());
// static_assert(!implements<&D3::f, &B::f>());
```

Reply via email to