www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - opCast for classes

reply =?UTF-8?B?Ikx1w61z?= Marques" <luismarques gmail.com> writes:
Hi there,

I've been away for a while from the D world, so I guess I missed 
some of the new things.

Regarding opCast, the documentation says:

"This only happens, however, for instances of structs. Class 
references are converted to bool by checking to see if the class 
reference is null or not."

Yet this works:

class B
{
     bool v;

     this(bool v)
     {
         this.v = v;
     }

     T opCast(T)()
     {
         return v;
     }
}

unittest
{
     B bfalse = new B(false);
     B btrue = new B(true);
     assert(cast(bool) bfalse == false);
     assert(cast(bool) btrue == true);
}

Is that a new feature? Can I rely on it? Is it documented 
somewhere?

Thanks! :-)

Regards,
Luís
Mar 12 2013
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 03/12/2013 01:08 PM, "Luís Marques" <luismarques gmail.com>" wrote:
 Hi there,

 I've been away for a while from the D world, so I guess I missed some of
 the new things.

 Regarding opCast, the documentation says:

 "This only happens, however, for instances of structs. Class references
 are converted to bool by checking to see if the class reference is null
 or not."

 Yet this works:

 class B
 {
 bool v;

 this(bool v)
 {
 this.v = v;
 }

 T opCast(T)()
 {
 return v;
 }
 }

 unittest
 {
 B bfalse = new B(false);
 B btrue = new B(true);
 assert(cast(bool) bfalse == false);
 assert(cast(bool) btrue == true);
 }

 Is that a new feature? Can I rely on it? Is it documented somewhere?

 Thanks! :-)

 Regards,
 Luís
I don't know what the intended behavior but there is a distinction between automatic vs. implicit. These pass as well: assert(bfalse); assert(btrue); So, apparently implicit conversion considers the class variable and explicit conversion considers the class object. And this produces a compilation error: B bnull; assert(cast(bool)bnull); Error: null dereference in function _D6deneme19__unittestL123991_1FZv Ali
Mar 12 2013
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Tuesday, 12 March 2013 at 20:17:33 UTC, Ali Çehreli wrote:
 On 03/12/2013 01:08 PM, "Luís Marques" <luismarques gmail.com>" 
 wrote:
 Hi there,

 I've been away for a while from the D world, so I guess I
missed some of
 the new things.

 Regarding opCast, the documentation says:

 "This only happens, however, for instances of structs. Class
references
 are converted to bool by checking to see if the class
reference is null
 or not."

 Yet this works:

 class B
 {
 bool v;

 this(bool v)
 {
 this.v = v;
 }

 T opCast(T)()
 {
 return v;
 }
 }

 unittest
 {
 B bfalse = new B(false);
 B btrue = new B(true);
 assert(cast(bool) bfalse == false);
 assert(cast(bool) btrue == true);
 }

 Is that a new feature? Can I rely on it? Is it documented
somewhere?
 Thanks! :-)

 Regards,
 Luís
I don't know what the intended behavior but there is a distinction between automatic vs. implicit. These pass as well: assert(bfalse); assert(btrue); So, apparently implicit conversion considers the class variable and explicit conversion considers the class object. And this produces a compilation error: B bnull; assert(cast(bool)bnull); Error: null dereference in function _D6deneme19__unittestL123991_1FZv Ali
bool toto = bfalse; // Error: cannot implicitly convert expression (bfalse) of type module.B to bool So it isn't the implicit cast kickin here, but a 3rd behavior. The kind of behavior that makes D so special and create theses edges cases we all love !
Mar 13 2013
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 03/13/2013 12:41 PM, deadalnix wrote:
 On Tuesday, 12 March 2013 at 20:17:33 UTC, Ali Çehreli wrote:
 ...
 So, apparently implicit conversion considers the class variable and
 explicit conversion considers the class object. And this produces a
 compilation error:

     B bnull;
     assert(cast(bool)bnull);

 Error: null dereference in function _D6deneme19__unittestL123991_1FZv

 Ali
bool toto = bfalse; // Error: cannot implicitly convert expression (bfalse) of type module.B to bool So it isn't the implicit cast kickin here, but a 3rd behavior. The kind of behavior that makes D so special and create theses edges cases we all love !
It's an unnecessary special case. assert(objRef); checks whether the object reference is not null and then it checks the object invariant. Walter thinks this is useful.
Mar 13 2013