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

--- Comment #2 from Casey Carter <Casey at Carter dot net> ---
Here's a somewhat minimized test case that illustrates that overload resolution
works correctly, but matching partial specializations of a class template or
variable template does not:

template <bool Value>
struct bool_ {
  static constexpr bool value {Value};
};
using true_type = bool_<true>;
using false_type = bool_<false>;

template <class...> struct all_same : true_type {};
template <class T, class...Rest>
struct all_same<T, T, Rest...> : all_same<T, Rest...> {};
template <class T, class U, class...Rest>
struct all_same<T, U, Rest...> : false_type {};

template <class...Ts>
concept bool Same() {
  return all_same<Ts...>::value;
}

template <class F, class...Args>
concept bool Function() {
  return requires (F& f, Args&&...args) {
    requires Same<int, decltype(f((Args&&)args...))>();
  };
}

template <class, class...>
constexpr bool function() { return false; }
Function{F, ...Args}
constexpr bool function() { return true; }

template <class, class...>
constexpr bool func_v = false;
Function{F, ...Args}
constexpr bool func_v<F, Args...> = true;

template <class, class...>
struct is_function : false_type {};
Function{F, ...Args}
struct is_function<F, Args...> : true_type {};

struct plus { int operator()(int) const; };

static_assert(function<::plus, int>());         // Fine
static_assert(func_v<::plus, int>);             // Error
static_assert(is_function<::plus, int>::value); // Error

Reply via email to