Connecting Tech Pros Worldwide Help | Site Map

ambiguous constructor? Is it right?

 
LinkBack Thread Tools Search this Thread
  #1  
Old September 25th, 2007, 11:25 AM
Zeppe
Guest
 
Posts: n/a
Default ambiguous constructor? Is it right?

Dear all,

I have the following problem, that I'll try to explain with a very
minimal example:

class A
{
};

class B
{
public:
B() { }
B(const A&) { }
B(const B&) { }
};

class C
{
public:
operator A() const { return A(); }
operator B() const { return B(); }
};

int main(){
const C& c = C();
B b = static_cast<B>(c);
return 0;
}


Basically, I would expect that casting a const C& to B would call the
operator B() of C and that the construction C -B (through the copy
constructor) would be preferred to C -A -B. In Visual C++ 9 it
actually does so, but gcc complains that there is an ambiguity. Who's
right (I guess Visual c++) and, in case, how could I nicely work around
the problem?

Thanks!

Zeppe

  #2  
Old September 25th, 2007, 11:45 AM
Barry
Guest
 
Posts: n/a
Default Re: ambiguous constructor? Is it right?

Zeppe wrote:
Quote:
Dear all,
>
I have the following problem, that I'll try to explain with a very
minimal example:
>
class A
{
};
>
class B
{
public:
B() { }
B(const A&) { }
B(const B&) { }
};
>
class C
{
public:
operator A() const { return A(); }
operator B() const { return B(); }
};
>
int main(){
const C& c = C();
B b = static_cast<B>(c);
return 0;
}
>
>
Basically, I would expect that casting a const C& to B would call the
operator B() of C and that the construction C -B (through the copy
what makes "operator B()" have higher priority?
Quote:
constructor) would be preferred to C -A -B. In Visual C++ 9 it
actually does so, but gcc complains that there is an ambiguity. Who's
right (I guess Visual c++) and, in case, how could I nicely work around
the problem?
>
gcc is right,
You can compile using VC with /Za option, which disables the extension,
and produces the compile error.
I know ya gonna complain. :-)

--
Thanks
Barry
  #3  
Old September 25th, 2007, 01:55 PM
Zeppe
Guest
 
Posts: n/a
Default Re: ambiguous constructor? Is it right?

Barry wrote:
Quote:
Zeppe wrote:
Quote:
>Dear all,
>>
>I have the following problem, that I'll try to explain with a very
>minimal example:
>>
>class A
>{
>};
>>
>class B
>{
>public:
> B() { }
> B(const A&) { }
> B(const B&) { }
>};
>>
>class C
>{
>public:
> operator A() const { return A(); }
> operator B() const { return B(); }
>};
>>
>int main(){
> const C& c = C();
> B b = static_cast<B>(c);
> return 0;
>}
>>
>>
>Basically, I would expect that casting a const C& to B would call the
>operator B() of C and that the construction C -B (through the copy
>
what makes "operator B()" have higher priority?
because I specified a method for the conversion of C into B, in C. I
would expect it to be called in the static cast. The other way (C->A->B)
implies one level of implicit conversion, doesn't it?
Quote:
Quote:
>constructor) would be preferred to C -A -B. In Visual C++ 9 it
>actually does so, but gcc complains that there is an ambiguity. Who's
>right (I guess Visual c++) and, in case, how could I nicely work
>around the problem?
>>
>
gcc is right,
You can compile using VC with /Za option, which disables the extension,
and produces the compile error.
I know ya gonna complain. :-)
No, I'm not, just a little bit disappointed :) And what about a
workaround? Is the only way to solve this to clean up one of the two
conversion ways?

Regards,

Zeppe

  #4  
Old September 25th, 2007, 02:05 PM
Barry
Guest
 
Posts: n/a
Default Re: ambiguous constructor? Is it right?

Zeppe wrote:
Quote:
Barry wrote:
Quote:
>Zeppe wrote:
Quote:
>>Dear all,
>>>
>>I have the following problem, that I'll try to explain with a very
>>minimal example:
>>>
>>class A
>>{
>>};
>>>
>>class B
>>{
>>public:
>> B() { }
>> B(const A&) { }
>> B(const B&) { }
>>};
>>>
>>class C
>>{
>>public:
>> operator A() const { return A(); }
>> operator B() const { return B(); }
>>};
>>>
>>int main(){
>> const C& c = C();
>> B b = static_cast<B>(c);
>> return 0;
>>}
>>>
>>>
>>Basically, I would expect that casting a const C& to B would call the
>>operator B() of C and that the construction C -B (through the copy
>>
>what makes "operator B()" have higher priority?
>
because I specified a method for the conversion of C into B, in C. I
would expect it to be called in the static cast. The other way (C->A->B)
implies one level of implicit conversion, doesn't it?
>
Quote:
Quote:
>>constructor) would be preferred to C -A -B. In Visual C++ 9 it
>>actually does so, but gcc complains that there is an ambiguity. Who's
>>right (I guess Visual c++) and, in case, how could I nicely work
>>around the problem?
>>>
>>
>gcc is right,
>You can compile using VC with /Za option, which disables the
>extension, and produces the compile error.
>I know ya gonna complain. :-)
>
No, I'm not, just a little bit disappointed :) And what about a
workaround? Is the only way to solve this to clean up one of the two
conversion ways?
>
I think it is, since it violates the standard.


--
Thanks
Barry
  #5  
Old September 25th, 2007, 02:25 PM
Zeppe
Guest
 
Posts: n/a
Default Re: ambiguous constructor? Is it right?

Barry wrote:
Quote:
Zeppe wrote:
Quote:
>No, I'm not, just a little bit disappointed :) And what about a
>workaround? Is the only way to solve this to clean up one of the two
>conversion ways?
>>
>
I think it is, since it violates the standard.
I guess the same. Thank you very much!

Regards,

Zeppe
  #6  
Old September 26th, 2007, 08:35 AM
James Kanze
Guest
 
Posts: n/a
Default Re: ambiguous constructor? Is it right?

On Sep 25, 3:58 pm, Barry <dhb2...@gmail.comwrote:
Quote:
Zeppe wrote:
Quote:
Barry wrote:
Quote:
Zeppe wrote:
>I have the following problem, that I'll try to explain with a very
>minimal example:
Quote:
Quote:
Quote:
>class A
>{
>};
Quote:
Quote:
Quote:
>class B
>{
>public:
> B() { }
> B(const A&) { }
> B(const B&) { }
>};
Quote:
Quote:
Quote:
>class C
>{
>public:
> operator A() const { return A(); }
> operator B() const { return B(); }
>};
Quote:
Quote:
Quote:
>int main(){
> const C& c = C();
> B b = static_cast<B>(c);
> return 0;
>}
Quote:
Quote:
Quote:
>Basically, I would expect that casting a const C& to B
>would call the operator B() of C and that the construction
>C -B (through the copy
Quote:
Quote:
Quote:
what makes "operator B()" have higher priority?
Quote:
Quote:
because I specified a method for the conversion of C into B,
in C. I would expect it to be called in the static cast. The
other way (C->A->B) implies one level of implicit
conversion, doesn't it?
According to §5.2.9/3 (static_cast):

Otherwise, an expression e can be explicitly converted
to a type T using a static_cast of the form
static_cast<T>(e) if the declaration T t(e); is
well-formed, for some invented temporary variable t
(8.5). The effect of such an explicit conversion is the
same as performing the declaration and initialization
and then using the temporary variable as the result of
the conversion. [...]

So overload resolution treats the expression as if it were:
B untamedTemp( c ) ;
(followed by B b( untamedTemp ) ;). B has two constructors, one
which takes a const A&, and one which takes a const B&. C can
convert (equally well) to one or the other.
Quote:
Quote:
Quote:
>constructor) would be preferred to C -A -B. In Visual C++ 9 it
>actually does so, but gcc complains that there is an ambiguity. Who's
>right (I guess Visual c++) and, in case, how could I nicely work
>around the problem?
Quote:
Quote:
Quote:
gcc is right,
You can compile using VC with /Za option, which disables the
extension, and produces the compile error.
I know ya gonna complain. :-)
Quote:
Quote:
No, I'm not, just a little bit disappointed :) And what about a
workaround? Is the only way to solve this to clean up one of the two
conversion ways?
Quote:
I think it is, since it violates the standard.
The "work-around" is to not define so many implicit conversions.
Generally, too many implicit conversions will lead to
ambiguities. And even if it doesn't, it leads to code which is
hard to understand and to maintain.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

 

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Popular Articles

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 220,662 network members.