This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++11 status.

### 1292. `std::function` should support all callable types

Section: 20.14.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 other active issues in [func.wrap.func.con].

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 20.14.3 [func.def]/3), even though the intent clearly is to be usable for all of them as described in 20.14.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 20.14.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 a `NULL` function pointer.
> > - `f` is a `NULL` 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 20.14.17.3 [func.wrap.func]/2 or 20.14.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 20.14.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 a `NULL` function pointer.
> > - `f` is a `NULL` pointer to member function pointer.
> > - `F` is an instance of the function class template, and `!f`

> > 11 Otherwise, `*this` targets a copy of `f` or, initialized with `std::move(f)` if `f` is not a pointer to member function, and targets a copy of `mem_fn(f)` if `f` is a pointer to member function. [Note: implementations are encouraged to avoid the use of dynamically allocated memory for small function objects, for example, where `f`'s target is an object holding only a pointer or reference to an object and a member function pointer. — end note]