1023. Unclear inheritance relation for std::function

Section: 23.14.13.2 [func.wrap.func] Status: NAD Editorial Submitter: Alisdair Meredith Opened: 2009-03-11 Last modified: 2016-02-10

Priority: Not Prioritized

View all other issues in [func.wrap.func].

View all issues with NAD Editorial status.

Discussion:

Addresses DE 22 [CD1]

Related to issue 1114.

The conditions for deriving from std::unary_function and std::binary_function are unclear: The condition would also be satisfied if ArgTypes were std::vector<T1>, because it (arguably) "contains" T1.

[ Summit: ]

Agree. std::reference_wrapper has the same structure, and we suggest that std::function be presented in the same way as std::reference_wrapper.

[ 2009-05-09 Alisdair adds: ]

Phrasing should be "publicly and unambiguously derived from" and probably back in reference_wrapper too. Updated wording supplied.

[ Batavia (2009-05): ]

We agree with the proposed wording. Move to NAD Editorial.

Proposed resolution:

(no changes to <functional> synopsis required)

Change synopsis in Class template function 23.14.13.2 [func.wrap.func]:

template<Returnable R, CopyConstructible... ArgTypes> 
class function<R(ArgTypes...)> 
  : public unary_function<T1, R>      // iff sizeof...(ArgTypes) == 1 and see below
                                      // ArgTypes contains T1
  : public binary_function<T1, T2, R> // iff sizeof...(ArgTypes) == 2 and see below
                                      // ArgTypes contains T1 and T2
{
   ...

Add new p1/p2 before 23.14.13.2.1 [func.wrap.func.con]:

The template instantiation function<R(T1)> shall be publicly and unambiguously derived from std::unary_function<T1,R> if and only if the template type parameter is a function type taking one argument of type T1 and returning R.

The template instantiation function<R(T1,T2)> shall be publicly and unambiguously derived from std::binary_function<T1,T2,R> if and only if the template type parameter is a function type taking two arguments of type T1 and T2 and returning R.

explicit function();