https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91456
Bug ID: 91456 Summary: std::function and std::is_invocable_r do not understand guaranteed elision Product: gcc Version: 9.1.1 Status: UNCONFIRMED Keywords: rejects-valid Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- // { dg-options "-std=gnu++17" } // { dg-do compile { c++17 } } #include <functional> struct Immovable { Immovable() = default; Immovable(const Immovable&) = delete; Immovable& operator=(const Immovable&) = delete; }; Immovable get() { return {}; } const Immovable i = get(); // OK std::function<const Immovable()> f{&get}; // fails const Immovable i2 = f(); It fails because std::function uses is_same<R1,R2> || is_convertible<R1,R2> to check if the target function's return type can be converted to the std::function return type. Immovable and const Immovable are not the same type, and is_convertible checks whether construction or R2 from R1&& is well-formed, so that fails too. It should succeed in C++17, because guaranteed elision means there's no copy from an rvalue.