Topic: Question on overload resolution
Author: Kevin_VanHorn@ndsu.nodak.edu (Kevin S. Van Horn)
Date: Thu, 17 Oct 2002 01:41:50 +0000 (UTC) Raw View
The following code seems to work, but I have doubts as to whether it
is legal according to the Standard:
----------
struct A { };
struct B : private A { };
struct X {
X() { }
X(A) { cout << "Called A ctor" << endl; }
X(B) { cout << "Called B ctor" << endl; }
X(X &) { cout << "Called non-const copy ctor" << endl; }
operator A() const { return A(); }
operator B() { return B(); }
};
...
X x(X());
----------
The X(X &) ctor cannot be called in the above definition of x, as
temporaries cannot be bound to non-const references. There are then
two possibilities:
- convert X() to type A and then call X(A) ctor, or
- convert X() to type B and then call X(B) ctor.
Is this ambiguous, or do the C++ overload resolution rules
unambiguously choose one of these two? If the latter, what are the
relevant paragraphs from the Standard?
---
[ 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: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 17 Oct 2002 08:44:24 +0000 (UTC) Raw View
Kevin S. Van Horn wrote:
> X x(X());
This declares a function named x which takes a single parameter
of type pointer to function with no parameters which returns X
and returns an X.
---
[ 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: vAbazarov@dAnai.com ("Victor Bazarov")
Date: Thu, 17 Oct 2002 15:02:29 +0000 (UTC) Raw View
"Hyman Rosen" <hyrosen@mail.com> wrote...
> Kevin S. Van Horn wrote:
> > X x(X());
>
> This declares a function named x which takes a single parameter
> of type pointer to function with no parameters which returns X
> and returns an X.
Actually, according to the Standard, the inner-most parentheses
do not matter and the statement is parsed as
X x(X);
which, of course, _is_ a function declaration, only it takes an
X as its parameter, not a function pointer (8.2/1).
Victor
--
Please remove capital A's from my address when replying by mail
---
[ 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: Kevin_VanHorn@ndsu.nodak.edu (Kevin S. Van Horn)
Date: Thu, 17 Oct 2002 15:02:56 +0000 (UTC) Raw View
Hyman Rosen wrote:
> Kevin S. Van Horn wrote:
> > X x(X());
>
> This declares a function named x which takes a single parameter
> of type pointer to function with no parameters which returns X
> and returns an X.
Oops, forgot about that particular syntactic booby trap. OK, let's
repeat the question, replacing that line with
X x((X()));
---
[ 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: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 17 Oct 2002 16:33:38 +0000 (UTC) Raw View
Kevin S. Van Horn wrote:
> struct A { };
> struct B : private A { };
>
> struct X {
> X() { } X(A) { } X(B) { } X(X &) { }
> operator A() const { return A(); }
> operator B() { return B(); }
> };
>
> X x((X()));
>
> Is this ambiguous, or do the C++ overload resolution rules
> unambiguously choose one of these two? If the latter, what are the
> relevant paragraphs from the Standard?
Unambiguous, choosing the B path. 8.5/14/4/2 tells us that x
will be initialized through a constructor. The available ones
are X(A) and X(B), so overload resolution has to decide which
one to call. The operand X() is non-const, so X::operator B
can be called on it directly, while X::operator A would first
require a qualification conversion, so by 13.3.3.2/3/4, the
first one is better, and X() gets converted to B and x is
constructed from that.
---
[ 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: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 17 Oct 2002 16:56:53 +0000 (UTC) Raw View
Victor Bazarov wrote:
> Actually, according to the Standard, the inner-most parentheses
> do not matter and the statement is parsed as
> X x(X);
> which, of course, _is_ a function declaration, only it takes an
> X as its parameter, not a function pointer (8.2/1).
I believe you are wrong. If you look at the grammar in 8.1/1,
an empty set of parentheses can only correspond to an empty
parameter declaration list, not to redundant parentheses
around a missing declarator.
If you were correct, it would lead to an unfortunate asymmetry
between 'void f(int(int))' and 'void f(int())'.
---
[ 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: Thu, 17 Oct 2002 18:01:09 +0000 (UTC) Raw View
On Thu, 17 Oct 2002 15:02:29 +0000 (UTC), vAbazarov@dAnai.com ("Victor
Bazarov") wrote:
> "Hyman Rosen" <hyrosen@mail.com> wrote...
> > Kevin S. Van Horn wrote:
> > > X x(X());
> > This declares a function named x which takes a single parameter
> > of type pointer to function with no parameters which returns X
> > and returns an X.
> Actually, according to the Standard, the inner-most parentheses
> do not matter and the statement is parsed as
> X x(X);
> which, of course, _is_ a function declaration, only it takes an
> X as its parameter, not a function pointer (8.2/1).
Look again. X x(X(a)) is parsed as X x(X a) is X x(X) because of
redundant parens around the a. However redundant parens are not
allowed around nothing and X x(X()) is parsed as X x(X(*)()) because
it is allowed to omit the (*) in a function pointer parameter.
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 ]