Connecting Tech Pros Worldwide Help | Site Map

ambiguous constructor? Is it right?

  #1  
Old September 25th, 2007, 12:25 PM
Zeppe
Guest
 
Posts: n/a
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, 12:45 PM
Barry
Guest
 
Posts: n/a

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, 02:55 PM
Zeppe
Guest
 
Posts: n/a

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, 03:05 PM
Barry
Guest
 
Posts: n/a

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, 03:25 PM
Zeppe
Guest
 
Posts: n/a

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, 09:35 AM
James Kanze
Guest
 
Posts: n/a

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

Closed Thread


Similar Threads
Thread Thread Starter Forum Replies Last Post
Is it possible to catch an exception raised by a member variable? Angus answers 12 September 29th, 2007 01:55 PM
conversion constructor Alexander Stippler answers 15 October 27th, 2005 12:55 PM
Why is this not ambiguous? REH answers 16 July 23rd, 2005 03:50 AM
Invoking constructor : Foo(var) and Foo ins(var) Alex Vinokur answers 4 July 19th, 2005 07:18 PM