Topic: Yet another "which overload" question


Author: pdimov@mmltd.net (Peter Dimov)
Date: Wed, 3 Jul 2002 16:11:04 GMT
Raw View
Hyman Rosen <hyrosen@mail.com> wrote in message news:<3D21EE9D.4030509@mail.com>...
> Peter Dimov wrote:
> > struct X { };
> > template<class T> struct Y { };
> > struct Z : X, Y<int> { };
> > void f(X const &) { }
> > template<class T> void f(Y<T> const &) { }
> > int main() { f(Z()); }
> >
> > Which 'f' overload should be chosen? The surprising answer is that f(X
> > const &) is a better match; this, IMO, leads to some very hard to find
> > bugs. (I just found one.) Is this behavior intentional, or is this a
> > defect?
>
> Intentional, se 13.3.3. In your particular case, the two bases
> X and Y<int> certainly have at least equal standing, so at best
> you could expect ambiguity. But other things being equal, a
> non-template is preferred over a template specialization, and so
> you get f(X) called.

Yes, I know that 13.3.3 says that a non-template is preferred over a
template specialization, but this tells me nothing about the intent.

By my interpretation, the overload resolution (and partial ordering)
rules are intended to select the most specialized function (by some
appropriate definition of specialized.)

In my example, neither function is more specialized than the other, in
the sense that given a X, Y<T> const & cannot bind to it, and given an
Y<T>, X const & cannot bind to it (if we look at the famous 14.5.5.2
for inspiration about what 'more specialized' could mean in this
case.)

I _think_ that the "non-template beats a template" rule was intended
to resolve cases like

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

(and other, more contrived variations thereof.)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: pdimov@mmltd.net (Peter Dimov)
Date: Tue, 2 Jul 2002 15:48:25 GMT
Raw View
Consider the program

struct X
{
};

template<class T> struct Y
{
};

struct Z: public X, public Y<int>
{
};

void f(X const &)
{
}

template<class T> void f(Y<T> const &)
{
}

int main()
{
    f(Z());
}

Which 'f' overload should be chosen? The surprising answer is that f(X
const &) is a better match; this, IMO, leads to some very hard to find
bugs. (I just found one.) Is this behavior intentional, or is this a
defect?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Hyman Rosen <hyrosen@mail.com>
Date: Tue, 2 Jul 2002 16:29:12 CST
Raw View
Peter Dimov wrote:
> struct X { };
> template<class T> struct Y { };
> struct Z : X, Y<int> { };
> void f(X const &) { }
> template<class T> void f(Y<T> const &) { }
> int main() { f(Z()); }
>
> Which 'f' overload should be chosen? The surprising answer is that f(X
> const &) is a better match; this, IMO, leads to some very hard to find
> bugs. (I just found one.) Is this behavior intentional, or is this a
> defect?

Intentional, se 13.3.3. In your particular case, the two bases
X and Y<int> certainly have at least equal standing, so at best
you could expect ambiguity. But other things being equal, a
non-template is preferred over a template specialization, and so
you get f(X) called.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jpotter@falcon.lhup.edu (John Potter)
Date: Tue, 2 Jul 2002 21:29:10 GMT
Raw View
On Tue,  2 Jul 2002 15:48:25 GMT, pdimov@mmltd.net (Peter Dimov)
wrote:

> struct Z: public X, public Y<int>
> {
> };

> void f(X const &)
> {
> }

> template<class T> void f(Y<T> const &)
> {
> }

> int main()
> {
>     f(Z());
> }
>
> Which 'f' overload should be chosen? The surprising answer is that f(X
> const &) is a better match; this, IMO, leads to some very hard to find
> bugs. (I just found one.) Is this behavior intentional, or is this a
> defect?

Why is this surprising?  Non-templates are always prefered to
templates.  If you add

void f (Y<int> const&);

it becomes ambiguous.  What did you expect from your example?

John

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]