std::function
should support all callable typesSection: 22.10.17.3.2 [func.wrap.func.con] Status: C++11 Submitter: Daniel Krügler Opened: 2009-12-19 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [func.wrap.func.con].
View all issues with C++11 status.
Discussion:
Some parts of the specification of std::function
is unnecessarily
restricted to a subset of all callable types (as defined in 22.10.3 [func.def]/3), even though the intent clearly is to be usable for
all of them as described in 22.10.17.3 [func.wrap.func]/1. This
argument becomes strengthened by the fact that current C++0x-compatible
compilers work fine with them:
#include <functional> #include <iostream> struct A { int foo(int i) const {return i+1;} }; struct B { int mem; }; int main() { std::function<int(const A&, int)> f(&A::foo); A a; std::cout << f(a, 1) << '\n'; std::cout << f.target_type().name() << '\n'; typedef int (A::* target_t)(int) const; target_t* p = f.target<target_t>(); std::cout << (p != 0) << '\n'; std::function<int(B&)> f2(&B::mem); B b = { 42 }; std::cout << f2(b) << '\n'; std::cout << f2.target_type().name() << '\n'; typedef int (B::* target2_t); target2_t* p2 = f2.target<target2_t>(); std::cout << (p2 != 0) << '\n'; }
The problematic passages are 22.10.17.3.2 [func.wrap.func.con]/10:
template<class F> function(F f); template <class F, class A> function(allocator_arg_t, const A& a, F f);...
10 Postconditions:
!*this
if any of the following hold:
f
is aNULL
function pointer.f
is aNULL
member function pointer.F
is an instance of the function class template, and!f
because it does not consider pointer to data member and all constraints based on function objects which like 22.10.17.3 [func.wrap.func]/2 or 22.10.17.3.6 [func.wrap.func.targ]/3. The latter two will be resolved by the proposed resolution of 870 and are therefore not handled here.
[ Post-Rapperswil: ]
Moved to Tentatively Ready after 5 positive votes on c++std-lib.
[ Adopted at 2010-11 Batavia ]
Proposed resolution:
Change 22.10.17.3.2 [func.wrap.func.con]/10+11 as indicated:
template<class F> function(F f); template <class F, class A> function(allocator_arg_t, const A& a, F f);...
10 Postconditions:
!*this
if any of the following hold:
f
is aNULL
function pointer.f
is aNULL
pointer to memberfunction pointer.F
is an instance of the function class template, and!f
11 Otherwise,
*this
targets a copy off
or, initialized withstd::move(f)
if. [Note: implementations are encouraged to avoid the use of dynamically allocated memory for small function objects, for example, wheref
is not a pointer to member function, and targets a copy ofmem_fn(f)
iff
is a pointer to member functionf
's target is an object holding only a pointer or reference to an object and a member function pointer. — end note]