Boost logo

Boost :

From: Jens Maurer (Jens.Maurer_at_[hidden])
Date: 2000-11-19 18:36:17


In its not1 and not2 functions, boost/functional.hpp uses the
equivalent of

template<class Pred>
void functor(const Pred&)
{
}

With this, Comeau C++ 4.2.44beta3 gives an error with the following type
deduction:

bool f();

int main()
{
  functor(f);
}

The error is:

"functor-deduction.cpp", line 13: error: no instance of function template
          "functor" matches the argument list
            argument types are: (bool ())
    functor(f);
    ^

While no other compiler seems to give an error, I think Comeau is correct.

Here is some analysis:

Section 8.5.3p1 [dcl.init.ref] of the Standard states:
"A variable declared to be a T& [...] shall be initialized by an object,
or function, of type T or by an object that can be converted into a T."

We have an (implicit) reference to function f with the type (bool (&)()).
The parameter is of type "const Pred&" and not of type "Pred &".
However, f is not of const reference type, so the types are incompatible.
Note that the quoted sentence expressly excludes function types in those
"that can be converted to T", thus the type must match exactly.

Also note that 14.8.2 paragraph 2 last bullet has explicit wording
regarding references to cv-qualified function type, but it only applies
to non-deduced (i.e. explicitly specified) template arguments.
The wording may want to say that references to cv-qualified function
types are never allowed in all cases, so the list is just the
list of things to be checked for non-deduced template arguments.

However, 8.5.3p4 does not say that it only applies to non-function
types when it talks about cv-qualification. Notwithstanding, I believe
that this only explains the "can be converted to T" part of 8.5.3p1 in
more detail.

Note also that the function-to-pointer standard conversion is only
applied if the parameter is not a reference (14.8.2.1p2 2nd bullet).

In short, I believe Comeau is correct and all declarations of not1, not2
in functional.hpp should be changed to

  template<class Pred>
  void functor(Pred p);

instead.

What's your opinion?

Jens Maurer


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk