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.

Reply via email to