By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,147 Members | 1,402 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,147 IT Pros & Developers. It's quick & easy.

Tricky conversions question

P: n/a
Here is a simplified version of a post I saw on another NG:

struct Base {};
struct Derived: Base {};

struct ConstPtr
{
//operator const Derived * (); // F1
operator const Derived * () const; // F2
private:
operator Derived * (); // F3
//operator Derived * () const; // F4
};

int main()
{
ConstPtr ptr;

const Derived * p3 = ptr;
const Base * p4 = ptr;
}

GCC fails both p3 and p4, for private access.
BCC allows p3 but fails p4 for the same reason.

Now consider the slightly modified version, where F1 and F4 are
un-commented.
GCC allows p3, and gives p4 as ambiguous.
BCC allows p3 but fails p4 for private access.

Can someone give me an detailed explanation, w.r.t the Standard,
of what's going on here? I've spent an hour poring over it and am
no closer to solving it really.
As far as I can see, p3+F2 is a standard conversion followed
by a user-defined conversion (both of "Equal Match" status),
and p3+F3 is a user-defined conversion followed by a standard
conversion (both of "Equal Match" status again), so why is one
preferred to the other?

Dec 14 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
Old Wolf wrote:
Here is a simplified version of a post I saw on another NG:

struct Base {};
struct Derived: Base {};

struct ConstPtr
{
//operator const Derived * (); // F1
operator const Derived * () const; // F2
private:
operator Derived * (); // F3
//operator Derived * () const; // F4
};

int main()
{
ConstPtr ptr;

const Derived * p3 = ptr;
const Base * p4 = ptr;
}

GCC fails both p3 and p4, for private access.
BCC allows p3 but fails p4 for the same reason.

Now consider the slightly modified version, where F1 and F4 are
un-commented.
GCC allows p3, and gives p4 as ambiguous.
BCC allows p3 but fails p4 for private access.

Can someone give me an detailed explanation, w.r.t the Standard,
of what's going on here? I've spent an hour poring over it and am
no closer to solving it really.
As far as I can see, p3+F2 is a standard conversion followed
by a user-defined conversion (both of "Equal Match" status),
and p3+F3 is a user-defined conversion followed by a standard
conversion (both of "Equal Match" status again), so why is one
preferred to the other?


I may have a few minutes tomorrow to look it over a bit closer,
but at this point I just tried the online Comeau thing and it
failed the original code by both private accesses (like GCC) and
lets everything fly once the F1 and F4 are uncommented.

V
Dec 14 '05 #2

P: n/a
Old Wolf wrote:
Here is a simplified version of a post I saw on another NG:

struct Base {};
struct Derived: Base {};

struct ConstPtr
{
//operator const Derived * (); // F1
operator const Derived * () const; // F2
private:
operator Derived * (); // F3
//operator Derived * () const; // F4
};

int main()
{
ConstPtr ptr;

const Derived * p3 = ptr;
const Base * p4 = ptr;
}

GCC fails both p3 and p4, for private access.
BCC allows p3 but fails p4 for the same reason.
C++ std 11.3p4
When overload resolution succeeds, and the best viable function is not
accessible (clause 11) in the context in which it is used, the program
is illformed.

In the current case, the overloaded resolution rules state that the
best viable function for p3 and p4 is F3. Since F3 is private, the
program is ill formed. Both the calls should be rejected.
Now consider the slightly modified version, where F1 and F4 are
un-commented.
GCC allows p3, and gives p4 as ambiguous.
BCC allows p3 but fails p4 for private access.

for p3 (most of it applies to p4 also):

C++ std 13.3.1.5p1
Conversion functions that return a cv-qualified type are considered to
yield the cv-unqualified version of that type for this process of
selecting candidate functions.

What this means is that operator const Derived*() is considered to be
at the same level as the operator Derived*() as far as the process of
selecting candidate functions. I am surprised (or rather, confused) on
observing that expression involving p3 gets compiled well.
for p4 :

13.3.3.1p6) [Note: there is no such standard conversion; this
derived-to-base
Conversion exists only in the description of implicit conversion
sequences.]

Thus, the derived-to-base conversion is listed as one of the implicit
conversions.
So we have two paths to take here -

a) ConstPtr --(operator Derived*) --> Derived* --(implicit
conversion)--> const Base*
b) ConstPtr --(operator const Derived*) --> const Derived* --(implicit
conversion)--> const Base*

And we are back to the same old issue - the first conversion step is
ambiguous - neither is better. So there also should be a compilation
error for p4.


Can someone give me an detailed explanation, w.r.t the Standard,
of what's going on here? I've spent an hour poring over it and am
no closer to solving it really.


Same here. Even now I am not sure, especially because Comeau online
accepts the second version of the code, whereas my (imperfect?)
analysis says that it shouldnot.

Dec 14 '05 #3

P: n/a
Neelesh Bodas wrote:
C++ std 13.3.1.5p1
Conversion functions that return a cv-qualified type are considered to
yield the cv-unqualified version of that type for this process of
selecting candidate functions.

What this means is that operator const Derived*() is considered to be
at the same level as the operator Derived*() as far as the process of
selecting candidate functions. I am surprised (or rather, confused) on
observing that expression involving p3 gets compiled well.


I interpret this section as only applying to the process of selecting
viable functions. Once we have determined that F1,F2,F3,F4 are
all viable functions, then this section is no longer relevant. In
particular, it does not apply to the process of determining how
"long" a conversion sequence is.

Can someone give me an detailed explanation, w.r.t the Standard,
of what's going on here? I've spent an hour poring over it and am
no closer to solving it really.


Same here. Even now I am not sure, especially because Comeau
online accepts the second version of the code, whereas my
(imperfect?) analysis says that it shouldnot.


Hopefully Greg will step in here.. :)

Dec 14 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.