Re: Compiler chooses conv ctor - why?



Hello,

Charles Wang[MSFT] wrote:

Could you please let me know why you think that this is a compiler bug? I think that this is just a way of compiler implementing conversion. In VC++, by default "B b=a" will call B's constructor "B(const A& a);" to perform the conversion; you can use "explicit" keyword before "B(const A& a);" to avoid such automatic constructor conversion, and then the conversion would happen on "A::operator const B() const".

Charles, thank you for the MSDN link. I've looked for an explanation of
such behaviour. Here it is. However, previously I've looked into ISO
14822 and have found no explanation. Those web pages have been finishing
my doubts.

I'm not very familiar with this ISO, as I've recently returned to C++
after a long period of time. However, I'll try to answer your question
and point out why this could be compiler bug. I'll refer to the original
ISO 14882 dated 2003-10-15, especially I'll not refer to the working
draft N2521 dated on February this year. Maybe something related
to this issue has changed after original ISO has been released, or maybe
I missed something. If somebody corrects me I'll be grateful.

1. By definition (8.5[12]) ,,B b=a;'' is copy-initialization (as
opposite to direct-initialization ,,B b(a);'' which drops away conv foos
and considers conv ctors only).

2. As class A and class B are not derived from each other, 8.5[14]
directs us to 13.3.1.4.

3. 13.3.1.4: candidate functions to invoke this task are conv ctor (
B::B(const A&); ), and conv foo ( A::operator B() const; ).

4. According to 13.3.3[1] we start at checking of parameter conversion
sequences, when selecting the best function. A parameter of conv ctor is
,,const A&'', and implicit object parameter of conv foo is ,,const A&''
too. Both of functions require the same qualification conversion, thus
both of them are indistinguishable from each other.

5. Next, according to the same 13.3.3[1], we land at the standard
conversion sequence of return types.

6. Both of foos return ,,B'', so no one is better then other, and
according to 13.3.3[2] the call (initialization) is ill-formed.

-- best regards

Cezary Noweta
.



Relevant Pages

  • Re: String^, const char*, std::string, and c_str( )
    ... Which hides the mechanics of the conversion. ... constants involved they are declared as const char* const constants. ... You can not really have the same code compile for .NET and ISO C++. ...
    (microsoft.public.dotnet.languages.vc)
  • Re: Anders Hejlsberg comment on immutable objects
    ... Immutability is a design goal that is achieved by use ... >>const, not an effect or result of const itself. ... I define improper as any conversion not fitting ... Unless the ability to cast away const was removed as you've ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: So many string types!
    ... > complains that it can not convert CHString to LPSTR. ... other .NET-languages only have one string type. ... AFAIK fopen expects a const char*, ... string class I know has a conversion to one of these types. ...
    (microsoft.public.dotnet.general)
  • Re: Operator overloading, well member function overload in general.
    ... It will also work if I remove the "const" modifier. ... that it's a const function requires a const conversion for the _object_ ... The compiler cannot decide. ... This is standard behaviour. ...
    (microsoft.public.vc.language)
  • Re: Smart pointers of const objets
    ... The problem is that you cannot bind a temporary object to a non-const ... the matching type) to a non-const reference. ... It will bind to a const reference though: ... Your conversion technique is actually ...
    (comp.lang.cpp)

Loading