Section: 16 [library] Status: NAD Submitter: Matt Austern Opened: 2002-10-23 Last modified: 2016-01-28
Priority: Not Prioritized
View other active issues in [library].
View all other issues in [library].
View all issues with NAD status.
Discussion:
Many function templates have parameters that are passed by value;
a typical example is find_if
's pred parameter in
26.6.6 [alg.find]. Are the corresponding template parameters
(Predicate
in this case) implicitly required to be
CopyConstructible, or does that need to be spelled out explicitly?
This isn't quite as silly a question as it might seem to be at first
sight. If you call find_if
in such a way that template
argument deduction applies, then of course you'll get call by value
and you need to provide a copy constructor. If you explicitly provide
the template arguments, however, you can force call by reference by
writing something like find_if<my_iterator,
my_predicate&>
. The question is whether implementation
are required to accept this, or whether this is ill-formed because
my_predicate& is not CopyConstructible.
The scope of this problem, if it is a problem, is unknown. Function object arguments to generic algorithms in clauses 26 [algorithms] and 29 [numerics] are obvious examples. A review of the whole library is necessary.
[ This is really two issues. First, predicates are typically passed by value but we don't say they must be Copy Constructible. They should be. Second: is specialization allowed to transform value arguments into references? References aren't copy constructible, so this should not be allowed. ]
[ 2007-01-12, Howard: First, despite the note above, references are copy constructible. They just aren't assignable. Second, this is very closely related to 92 and should be consistent with that. That issue already says that implementations are allowed to copy function objects. If one passes in a reference, it is copyable, but susceptible to slicing if one passes in a reference to a base. Third, with rvalue reference in the language one only needs to satisfy MoveConstructible to pass an rvalue "by value". Though the function might still copy the function object internally (requiring CopyConstructible). Finally (and fwiw), if we wanted to, it is easy to code all of the std::algorithms such that they do not copy function objects internally. One merely passes them by reference internally if desired (this has been fully implemented and shipped for several years). If this were mandated, it would reverse 92, allowing function objects to reliably maintain state. E.g. the example in 92 would reliably remove only the third element. ]
Proposed resolution:
Recommend NAD.
Rationale:
Generic algorithms will be marked with concepts and these will imply a requirement of MoveConstructible (not CopyConstructible). The signature of the function will then precisely describe and enforce the precise requirements.