https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119813
Bug ID: 119813 Summary: std::is_invocable thinks void can be passed to ... Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: blubban at gmail dot com Target Milestone: --- #include <type_traits> void a(...); bool b() { return std::is_invocable_v<decltype(a), void>; } template<typename T> bool c() { return requires { a(std::declval<T>()); }; } bool d() { return c<void>(); } or, somewhat shorter: #include <type_traits> static_assert(!std::is_invocable_v<void(*)(...), void>); Expected: Both b and d should be false. declval<void>() is illegal, so so the expression INVOKE(declval<Fn>(), declval<ArgTypes>()...) is not well-formed when treated as an unevaluated operand. Actual: b is true, d is false. https://godbolt.org/z/3KK63MYxY