-
Notifications
You must be signed in to change notification settings - Fork 24
Description
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.