This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++17 status.
std::function and std::reference_wrapperSection: 22.10.17.3.2 [func.wrap.func.con] Status: C++17 Submitter: Jonathan Wakely Opened: 2016-10-13 Last modified: 2017-07-30
Priority: 0
View all other issues in [func.wrap.func.con].
View all issues with C++17 status.
Discussion:
template<class F> function(F f) says that the effects are "*this
targets a copy of f" which seems pretty clear that if F is
reference_wrapper<CallableType> then the target is a
reference_wrapper<CallableType>.
f's target is a callable object passed via
reference_wrapper or a function pointer." From the requirement above
it's impossible for the target to be "a callable object passed via
reference_wrapper" because if the function was constructed with such a
type then the target is the reference_wrapper not the callable object
it wraps.
This matters because it affects the result of function::target_type(),
and we have implementation divergence. VC++ and libc++ store the
reference_wrapper as the target, but libstdc++ and Boost.Function
(both written by Doug Gregor) unwrap it, so the following fails:
#include <functional>
#include <cassert>
int main()
{
auto f = []{};
std::function<void()> fn(std::ref(f));
assert(fn.target<std::reference_wrapper<decltype(f)>>() != nullptr);
}
If std::function is intended to deviate from boost::function this way
then the Throws element for the copy and move constructors is
misleading, and should be clarified.
[2016-11-12, Issaquah]
Sat AM: Priority 0; move to Ready
Proposed resolution:
This wording is relative to N4606.
Modify 22.10.17.3.2 [func.wrap.func.con] p4 and p6 the same way, as shown:
function(const function& f);-3- Postconditions:
-4- Throws: shall not throw exceptions if!*thisif!f; otherwise,*thistargets a copy off.target().f's target is acallable object passed viaspecialization ofreference_wrapperor a function pointer. Otherwise, may throwbad_allocor any exception thrown by the copy constructor of the stored callable object. [Note: Implementations are encouraged to avoid the use of dynamically allocated memory for small callable objects, for example, wheref's target is an object holding only a pointer or reference to an object and a member function pointer. — end note]function(function&& f);-5- Effects: If
-6- Throws: shall not throw exceptions if!f,*thishas no target; otherwise, move constructs the target offinto the target of*this, leavingfin a valid state with an unspecified value.f's target is acallable object passed viaspecialization ofreference_wrapperor a function pointer. Otherwise, may throwbad_allocor any exception thrown by the copy or move constructor of the stored callable object. [Note: Implementations are encouraged to avoid the use of dynamically allocated memory for small callable objects, for example, wheref's target is an object holding only a pointer or reference to an object and a member function pointer. — end note]