Jump to page: 1 2
Thread overview
Overloading opCast with multiple types
Sep 30, 2006
Reiner Pope
Oct 01, 2006
Kristian
Oct 01, 2006
Kristian
Oct 01, 2006
Georg Wrede
Oct 02, 2006
Derek Parnell
Oct 03, 2006
Kristian
Newsreaders (was: Overloading opCast with multiple types)
Oct 23, 2006
Stewart Gordon
Oct 01, 2006
Stewart Gordon
Oct 03, 2006
pragma
Oct 03, 2006
Stewart Gordon
Oct 03, 2006
Pragma
Oct 01, 2006
Kristian
Oct 03, 2006
Stewart Gordon
Oct 03, 2006
J Duncan
Oct 03, 2006
Kristian
September 30, 2006
As we all know, opCast can only have one overload per class, because D doesn't support overloading by return type. That is a really silly limitation, in my opinion. Anyway, I have a solution here: give it a parameter, which is the type (we pass this parameter in the form of a template). Here's the magic:

class Test
{
	int x;
	Foo myCast(TFoo : Foo)() { static assert(is(TFoo == Foo), "No cast of the required type exists"); return new Foo(x); }
	Bar myCast(TBar : Bar)() { static assert(is(TBar == Bar),  "No cast of the required type exists"); return new Bar(x); }
	FooExtender2 myCast(T : FooExtender2)() { static assert(is(T == FooExtender2), "No cast of the required type exists"); return new FooExtender2(x); }
	this(int _x) {x = _x;}
}

and it is called like this:

	Test a = new Test(5);
	Foo f = a.myCast!(Foo); // Property syntax means the second () is unnecessary, so it looks almost like cast(Foo)a;
	Bar b = a.myCast!(Bar);
//	Useless u = a.myCast!(Useless); // Fails -- no template specialization exists
//	FooExtender t = a.myCast!(FooExtender); // Fails the static assert (TFoo == Foo)

This code works right now. The static asserts are necessary because template specialization doesn't have the expressiveness of is expressions. I want the ability to say, "use this specialization for this type only, and don't use it for the subtypes."

If this were supported under opCast, I would say that it should work by using templates as I have above, and adding a specialization type, so that templates could look like this: myCast(TFoo == Foo)() { return new Foo(x); }. (The '==' syntax is the noteworthy bit)

Let me know what you think,

Reiner
October 01, 2006
On Sun, 01 Oct 2006 01:25:15 +0300, Reiner Pope <reiner.pope@REMOVE.THIS.gmail.com> wrote:
> As we all know, opCast can only have one overload per class, because D doesn't support overloading by return type. That is a really silly limitation, in my opinion. Anyway, I have a solution here: give it a parameter, which is the type (we pass this parameter in the form of a template). Here's the magic:
>
> class Test
> {
> 	int x;
> 	Foo myCast(TFoo : Foo)() { static assert(is(TFoo == Foo), "No cast of the required type exists"); return new Foo(x); }
> 	Bar myCast(TBar : Bar)() { static assert(is(TBar == Bar),  "No cast of the required type exists"); return new Bar(x); }
> 	FooExtender2 myCast(T : FooExtender2)() { static assert(is(T == FooExtender2), "No cast of the required type exists"); return new FooExtender2(x); }
> 	this(int _x) {x = _x;}
> }
[snip]

Actually I was thinking something similar a while ago. Then I thought that maybe there is only one opCast() for a reason. And you could use functions as 'toString()' to do the casting (but, yeah, that's explicit).

Anyway, I think the opCasts can also be implemented as follows:

class Obj {
    int opCast(out int dst) {return(dst = ...);}
    Foo opCast(out Foo dst) {return(dst = ...);}
}

Or in some other way which don't complicate the implementation of compilers. (Of course, the previous syntax makes it cumbersome to call opCasts by yourself (e.g. "obj.opCast(tmp);"), but you're supposed to use cast statements anyway (e.g. "cast(int)obj").)


Finally I have to say that I think the implicit type casting in C++ could work better. For example:

class String {
    operator int() const;
    operator char *() const;
};

void func(int v);
void func(char *s);

String s;
func(s);  //error: ambigious call

Because 'String' can be casted to 'int' and 'char *', the compiler don't know which one to use. Of course, 's' should be casted to 'char *' because the class represents a string (i.e. 'char *').

This could be solved by using some kind of preference ordering. For example (don't pay attention to the syntax):

class String {
    preference 2 operator int() const;
    preference 1 operator char *() const;  //prefer 'char *' over 'int'
};

So, if D will have multiple opCasts along with the implicit type conversion, maybe something similar could be used to solve problems with implicit casting.
October 01, 2006
"Kristian" <kjkilpi@gmail.com> wrote in message news:op.tgqne1b35xlco7@mist...

-------------------------------------------
Anyway, I think the opCasts can also be implemented as follows:

class Obj {
     int opCast(out int dst) {return(dst = ...);}
     Foo opCast(out Foo dst) {return(dst = ...);}
}

Or in some other way which don't complicate the implementation of
compilers. (Of course, the previous syntax makes it cumbersome to call
opCasts by yourself (e.g. "obj.opCast(tmp);"), but you're supposed to use
cast statements anyway (e.g. "cast(int)obj").)
--------------------------------------------

Of course, with that method, something like

Obj o = new Obj();
func(cast(int)o);

Wouldn't work, because there is no location to pass into the opCast; it's just a temporary.

I've gotten quite used to just having ".toXXX" or ".asXXX" methods.  It can be far more obvious what you're doing, and you can pass additional parameters to it unlike a cast.  That, and it can look nicer too:

int x = (cast(ArrayType)object)[4];

vs

int x = object.asArrayType[4];


October 01, 2006
On Sun, 01 Oct 2006 18:24:50 +0300, Jarrett Billingsley <kb3ctd2@yahoo.com> wrote:
> "Kristian" <kjkilpi@gmail.com> wrote in message
> news:op.tgqne1b35xlco7@mist...
>
> -------------------------------------------
> Anyway, I think the opCasts can also be implemented as follows:
>
> class Obj {
>      int opCast(out int dst) {return(dst = ...);}
>      Foo opCast(out Foo dst) {return(dst = ...);}
> }
>
> Or in some other way which don't complicate the implementation of
> compilers. (Of course, the previous syntax makes it cumbersome to call
> opCasts by yourself (e.g. "obj.opCast(tmp);"), but you're supposed to use
> cast statements anyway (e.g. "cast(int)obj").)
> --------------------------------------------
>
> Of course, with that method, something like
>
> Obj o = new Obj();
> func(cast(int)o);
>
> Wouldn't work, because there is no location to pass into the opCast; it's
> just a temporary.

Well yes, unless the compiler generates a temporary object that will be valid within the scope. For example, the previous example, will become:

    int _tmp;
    Obj o = new Obj();
    func(o.opCast(_tmp));

The syntax of opCast() is a matter of implementation only: which is the simpliest way for the compiler. If not, then the C++ styled operators could be used in D also. BTW, you could also have:

class Obj {
     int opCast(int) {return(...);}
     Foo opCast(Foo) {return(...);}
}

Parameters are just used to overload the operators.


>
> I've gotten quite used to just having ".toXXX" or ".asXXX" methods.  It can
> be far more obvious what you're doing, and you can pass additional
> parameters to it unlike a cast.  That, and it can look nicer too:
>
> int x = (cast(ArrayType)object)[4];
>
> vs
>
> int x = object.asArrayType[4];
>
>

Yep, I also prefer such functions over cast statements.
But if D would have implicit type conversion with multiple opCasts, then you could just do "x = y;". Would this be a good thing?... I don't know. (Surely it would be less informative, if nothing else.)
October 01, 2006
Reiner Pope wrote:
> As we all know, opCast can only have one overload per class, because D doesn't support overloading by return type. That is a really silly limitation, in my opinion. Anyway, I have a solution here: give it a parameter, which is the type (we pass this parameter in the form of a template). Here's the magic:
> 
> class Test
> {
>     int x;
>     Foo myCast(TFoo : Foo)() { static assert(is(TFoo == Foo), "No cast of the required type exists"); return new Foo(x); }
<snip>

Something to this effect has been proposed before.

However, the idea of having to put a static assert in each would make it somewhat more cumbersome than it should be.  Moreover, a problem with using templates is deciding how the vtbl would work.

There have been a number of proposals for ways to do multiple casts.

http://www.prowiki.org/wiki4d/wiki.cgi?FeatureRequestList

My proposal:

http://tinyurl.com/p2pn4

Stewart.


-- 
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCS/M d- s:-@ C++@ a->--- UB@ P+ L E@ W++@ N+++ o K-@ w++@ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++++ h-- r-- !y
------END GEEK CODE BLOCK------

My e-mail is valid but not my primary mailbox.  Please keep replies on the 'group where everyone may benefit.
October 01, 2006
"Kristian" <kjkilpi@gmail.com> wrote in message news:op.tgq6xi1s5xlco7@mist...
---------------------------------------------
Yep, I also prefer such functions over cast statements.
But if D would have implicit type conversion with multiple opCasts, then
you could just do "x = y;". Would this be a good thing?... I don't know.
(Surely it would be less informative, if nothing else.)
---------------------------------------------

(my newsreader does not like quoting your posts for some reason!)

Walter has expressed his.. disgust?  Lack of support?  for C++-style implicit casts, and I agree with him to an extent.  For trying to make "value" types (such as a BigInteger class or something), not having implicit casts can make it cumbersome to use the class, but to be honest, I've never had to write such a type.

In any case, I wouldn't cross my fingers for anything like this to happen soon ;)


October 01, 2006
On Sun, 01 Oct 2006 01:25:15 +0300, Reiner Pope <reiner.pope@REMOVE.THIS.gmail.com> wrote:

> As we all know, opCast can only have one overload per class, because D doesn't support overloading by return type. That is a really silly limitation, in my opinion.
[snip]

I think it's not important to consider how overloadable opCasts can be implemented.

The documentation indeed states "Since functions cannot be overloaded based on return value, there can be only one opCast per struct or class.", but that's not the actual reason why there is only one opCast. It may be a practical reason (which makes compiler implementation simplier), but it's not a physical restriction preventing multiple opCasts. The compiler could very well support the following:

class Obj {
    int opCast();
    float opCast();
}

It just depends on how one makes the compiler parse source files.

So, first we should discuss if there should be more than one opCast, and should there be implicit type conversion. How should it work in ambigious cases. Is that a reason why there is only one opCast? Or is it because implicit conversion makes code harder to read (it's less informative)?
October 01, 2006
Jarrett Billingsley wrote:
> "Kristian" <kjkilpi@gmail.com> wrote in message news:op.tgq6xi1s5xlco7@mist...
> ---------------------------------------------
> Yep, I also prefer such functions over cast statements.
> But if D would have implicit type conversion with multiple opCasts, then
> you could just do "x = y;". Would this be a good thing?... I don't know.
> (Surely it would be less informative, if nothing else.)
> ---------------------------------------------
> 
> (my newsreader does not like quoting your posts for some reason!)

In addition to quoting difficulties, are you not familiar with the security and usage issues Microsoft Outlook Express v 6 has?

Most other people here are already using something else.
October 01, 2006
"Georg Wrede" <georg.wrede@nospam.org> wrote in message news:45203A8F.6030800@nospam.org...
> In addition to quoting difficulties, are you not familiar with the security and usage issues Microsoft Outlook Express v 6 has?
>
> Most other people here are already using something else.

Man, I'd better just go with the flow, hm?  I sure don't want to be left out.

This is the only newsgroup I read, and Kristian is the only user whose posts don't quote right.  I think I can live with OE.


October 02, 2006
On Sun, 1 Oct 2006 18:59:00 -0400, Jarrett Billingsley wrote:

> "Georg Wrede" <georg.wrede@nospam.org> wrote in message news:45203A8F.6030800@nospam.org...
>> In addition to quoting difficulties, are you not familiar with the security and usage issues Microsoft Outlook Express v 6 has?
>>
>> Most other people here are already using something else.
> 
> Man, I'd better just go with the flow, hm?  I sure don't want to be left out.
> 
> This is the only newsgroup I read, and Kristian is the only user whose posts don't quote right.  I think I can live with OE.

LOL... I used to think that way too until I actually tried a purpose-built newsreader that adhered to standards. I'll never go back to that toy newsreader again.

-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Down with mediocrity!"
2/10/2006 10:01:16 AM
« First   ‹ Prev
1 2