Thread overview
opCast for classes
Mar 12, 2013
Luís Marques
Mar 12, 2013
Ali Çehreli
Mar 13, 2013
deadalnix
Mar 13, 2013
Timon Gehr
March 12, 2013
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
March 12, 2013
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

March 13, 2013
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 !
March 13, 2013
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.