From: Kris Prad on 22 Apr 2010 08:19 Testing implicit conversions using this contrived code: struct B; struct A { A() {} A(const B& ) // ------------ (1) { } }; struct B { // casting: used if (1) is not available operator A() // ------------- (2) { return A(); } }; void TestImplicitConv() { B b; A a1 = b; // ok, invokes (1) A a2; // VS2008 complains if there is no assignment op, ok on Comeau a2 = b; // -------- (3) } Comeau accepts (3), but which one takes precedence? (1) or (2)? VS2008 accepts this in any of the following cases: -- (3) is changed to a2 = (A) b , i.e. explicit cast -- if assignment op is defined in class A: A& operator=(const B& b) (unlike Comeau) -- if (1) is rermoved, in which case (2) is used even without explicit cast Is the compiler doing it right? Kris -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Paul Bibbings on 22 Apr 2010 22:14 Kris Prad <krisprad(a)yahoo.co.uk> writes: > Testing implicit conversions using this contrived code: > > struct B; > struct A > { > A() {} > A(const B& ) // ------------ (1) > { > } > }; > > struct B > { > // casting: used if (1) is not available > operator A() // ------------- (2) > { > return A(); > } > }; > > > void TestImplicitConv() > { > B b; > A a1 = b; // ok, invokes (1) > A a2; > // VS2008 complains if there is no assignment op, ok on Comeau > a2 = b; // -------- (3) > } To be specific here, VS2008 is not /solely/ complaining about the lack of a matching assignment op. To give the error message in full (compiled using 2008 Express): d:\CPPProjects\CLCPP>cl /EHsc -c implicit_conv.cpp Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. implicit_conv.cpp implicit_conv.cpp(24) : error C2679: binary '=' : no operator found which takes a right-hand operand of type 'B' (or there is no acceptable conversion) implicit_conv.cpp(9): could be 'A &A::operator =(const A &)' while trying to match the argument list '(A, B)' More pertinent here is the second part of the error (rather than that there is "no operator found which takes a right-hand operand of type 'B'"): "(or there is no acceptable conversion)" The compiler accepts the presence of the implicitly-defined default copy assignment: A& A::operator=(const A&) but what it doesn't appear to be happy with is the fact that there might be a valid conversion that will permit this to be called. Note, also, that the compiler is *not* reporting that conversions are available but that these are ambiguous. > > Comeau accepts (3) as does gcc: 09:45:06 Paul Bibbings(a)JIJOU /cygdrive/d/CPPProjects/CLCPP $i686-pc-cygwin-gcc-4.4.3 -c implicit_conv.cpp 09:45:38 Paul Bibbings(a)JIJOU /cygdrive/d/CPPProjects/CLCPP $ and it is worth looking at how gcc is resolving this (in order to provide an example, at least, against which to consider you next question): 09:47:42 Paul Bibbings(a)JIJOU /cygdrive/d/CPPProjects/CLCPP $i686-pc-cygwin-gcc-4.4.3 -S implicit_conv.cpp 09:48:00 Paul Bibbings(a)JIJOU /cygdrive/d/CPPProjects/CLCPP $cat implicit_conv.s <snip /> __Z16TestImplicitConvv: ; void TestImplicitConv() LFB7: pushl %ebp LCFI6: movl %esp, %ebp LCFI7: subl $20, %esp LCFI8: leal -2(%ebp), %eax movl %eax, (%esp) call __ZN1Bcv1AEv ; B::operator A() / A a1 = b; movb %al, -3(%ebp) leal -4(%ebp), %eax movl %eax, (%esp) call __ZN1AC1Ev ; A::A() / A a2; leal -2(%ebp), %eax movl %eax, (%esp) call __ZN1Bcv1AEv ; B::operator A() / a2 = b; movb %al, -1(%ebp) leal -1(%ebp), %edx leal -4(%ebp), %eax cmpl %eax, %edx leave ret LFE7: As I say, this is only by way of a comparative example, but it appears to show (note: my assembler is not that good) that gcc is prefering B::opA() to the converting constructor for both: A a1 = b; and: a2 = b; > , but which one takes precedence? (1) or (2)? `Chapter and Verse' from the Standard is required here, which I do not have access to at the present time. No doubt someone else will provide this promptly. > VS2008 accepts this in any of the following cases: > -- (3) is changed to a2 = (A) b , i.e. explicit cast > > -- if assignment op is defined in class A: A& operator=(const B& b) > (unlike Comeau) > > -- if (1) is rermoved, in which case (2) is used even without explicit > cast > > Is the compiler doing it right? I would suggest, strongly not. Regards Paul Bibbings -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
|
Pages: 1 Prev: Implicit conversions for value subtyping Next: need help learning c++ |