Topic: Are these "implicit" casts legal?


Author: Masanori Nakazato <nakazato@itc.ei.nsc.co.jp>
Date: 1996/04/22
Raw View
I am Japanease, so I cannot tell English fluently.
But I can point out the problem in your code.

it's this:
 You can cast Ref<B> to B* or to A*, because there
is Ref<B>::operator B*() and B is derived form A.
 But you cannot cast Ref<B> to Ref<A>, because
Ref<B> is not derived from Ref<A>.

Masanori Nakazato
Nippon Steel co.
nakazato@itc.ei.nsc.co.jp
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Jack Reeves <76217.2354@CompuServe.COM>
Date: 1996/04/23
Raw View
Angelo Salvade writes:

>Can anybody tell me if the following code is legal:
> ...
>I believe that #1-4 should work identically and are correct C++:
>A Ref<A> should be initialised with a Ref<B>.
>The following steps should happen:
>- call of Ref<B>.operator B*()
>- C++ built in conversion of B* to A*
>- call of constructor Ref<A>(A*)

1 & 3 are valid C++ and should work. 2 & 4 are invalid and should
generate compile errors.  The reason is that the compiler is
allowed to implicitly perform one(1) user defined conversion in
an attempt to coerce a parameter to the right type.  In 1 & 3
the user defined "operator B*() can be used.  In 2 & 4, this
has to be followed by the construction of a Ref<A> object, which
would be a second user defined conversion, and is not allowed.


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: saa@ecofin.ch (Angelo Salvade)
Date: 1996/04/19
Raw View
Can anybody tell me if the following code is legal:

//----------------------------------------------------------------

class A {};

class B: public A {};

//----------------------------------------------------------------

// with templates

template <class O>
class Ref {
 public:
  Ref();
  Ref(O* value);
  operator O*();
};

extern void f1(Ref<A> a);

static void t1()
{
 Ref<B> b;
 Ref<A> a(b); // #1

 f1(b); // #2
}

//----------------------------------------------------------------

// without templates

class RefA {
 public:
  RefA(A* value);
};

class RefB {
 public:
  RefB();
  operator B*();
};

extern void f2(RefA a);

static void t2()
{
 RefB b;
 RefA a(b); // #3

 f2(b); // #4
}

//----------------------------------------------------------------

I believe that #1-4 should work identically and are correct C++:
A Ref<A> should be initialised with a Ref<B>.
The following steps should happen:
- call of Ref<B>.operator B*()
- C++ built in conversion of B* to A*
- call of constructor Ref<A>(A*)

I checked this code with the Metrowerks CW8,
GNU 2.7.2 and SunPro C++ 4.0.1 & C++ 4.1 compilers.
The SunPro C++ 4.1 is the only compiler of those
that didn't compile #2 and #4. It gave the following message:
"Error: Cannot use Ref<B> to initialize Ref<A>".

Is my code illegal or is this a bug in the compiler?

Angelo Salvade
salvade@ecofin.ch
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]