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:
!*thisif any of the following hold:
fis aNULLfunction pointer.fis aNULLmember function pointer.Fis 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:
!*thisif any of the following hold:
fis aNULLfunction pointer.fis aNULLpointer to memberfunction pointer.Fis an instance of the function class template, and!f11 Otherwise,
*thistargets a copy offor, initialized withstd::move(f)if. [Note: implementations are encouraged to avoid the use of dynamically allocated memory for small function objects, for example, wherefis not a pointer to member function, and targets a copy ofmem_fn(f)iffis 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]