Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2001-09-19 07:12:26

From: "Darin Adler" <darin_at_[hidden]>
> on 9/18/01 5:11 PM, Douglas Gregor at gregod_at_[hidden] wrote:
> > But this requires partial ordering of function templates when a function
> > pointer is passed in, which breaks on a _lot_ of compilers.
> Your response inspired me to study the C++ standard section on partial
> ordering of function templates. My testing indicates that partial ordering
> of function templates works perfectly in the Metrowerks compiler even in
> cases where a function pointer is passed in. But your suggested fix for
> function constructor won't work. Here's why:
> template<typename F> function(const F& f);
> template<typename OR> function(OR (*f)());
> According to the rules in the standard (, neither of these
> templates is at least as specialized as the other! So there's an
> The rule is that you perform argument deduction on each of the templates,
> using parameters constructed by substituting unique types for each of the
> template parameters of the other. Trying to pass the function pointer type
> into the "const F&" results in a deduction that succeeds, but the deduced
> parameter type is not an exact match. The function pointer has to be
> implicitly converted into a const reference to a function pointer, which
> not allowed (

Your analysis is incorrect, I believe. A reference binding doesn't count as
an implicit conversion. Consider this simpler example:

template<class T> void f(T const &);
template<class T> void f(T * const &);

The problem with is that it does not specify how the argument
deduction is performed. The two possibilities are (1) deduction as in a
function call, and (2) deduction as in taking a function address.

Under (1) the function pointer version is more specialized. Under (2)
neither is. See

The modification

template<class F> void f(F const &);
template<class R> void f(R (* const &)());

'works' under both; but then the problem is that some compilers bind a const
reference to a function (which is currently not allowed but there is a
defect report against it - #295) and will therefore prefer the first
version. ;-)

My own opinion is that

template<class F> void function(F f);

is not that bad. The standard library always takes function objects by

Peter Dimov
Multi Media Ltd.

Boost list run by bdawes at, gregod at, cpdaniel at, john at