TartanLlama / function_ref

A lightweight, non-owning reference to a callable.
Creative Commons Zero v1.0 Universal
169 stars 23 forks source link

Cannot use with non-copyable, non-movable return types in function signatures #20

Open burnpanck opened 3 years ago

burnpanck commented 3 years ago

In C++17 and later the new mandatory ellision of copy/move operations allow the following function:

NonCopyNonMoveType f() {
  return NonCopyNonMoveType();
}

even if NonCopyNonMoveType has neither an accessible copy constructor nor an accessible move constructor.

Given that definition of f, also the following is valid

NonCopyNonMoveType g() {
  return f();
}

However, the expression function_ref<NonCopyNonMoveType()>(f) will not compile.

The usual constructor is disabled because the requirement std::is_convertible_v<std::invoke_result_t<decltype(f)>,NonCopyNonMoveType> is not met. That is the case because convertibility tests the possibility to construct a new function_ref return value from an rvalue of an existing return value of the supplied callable (in this case, it would be a move). However, under the new move ellision rules, no such move will actually happen. Therefore, in this case, the requirement rejects a callable that would be perfectly valid.