https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66998
Bug ID: 66998 Summary: not_fn invocation is not SFINAE friendly Product: gcc Version: 5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: tomaszkam at gmail dot com Target Milestone: --- According to the http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4529.html#func.not_fn the following invocations not_fn(f)(args...) and !INVOKE(f, args...) (in case when f is function object it can be simplified to !f(args)). However the in current implementation they behavior differs in case when they are used in SFINAE context. For example: #include <experimental/functional> template<typename F, typename Arg> auto foo1(F f, Arg arg) -> decltype(!f(arg)) { return !f(arg); } template<typename F, typename Arg> auto foo1(F f, Arg arg) -> decltype(!f()) { return !f(); } template<typename F, typename Arg> auto foo2(F f, Arg arg) -> decltype(not_fn(f)(arg)) { return not_fn(f)(arg); } template<typename F, typename Arg> auto foo2(F f, Arg arg) -> decltype(not_fn(f)()) { return not_fn(f)(); } struct negator { bool operator()(int) const { return false; } void operator()() const {} }; int main() { foo1(negator{}, 1); // foo2(negator{}, 1)); //Shall be equivalent to line above. Produces an compilation error cause by instatiation error during return type deduction. }; The problem is caused by the use of return type deduction (decltype(auto)) instead of decltype(expr) in the implementation of not_fn. Notice that such use does not break the function precondition placed in requires clause.