Is there a standard way to define to for user-defined types?

Paul D. Anderson paul.d.removethis.anderson at comcast.andthis.net
Sun Jun 19 20:56:28 PDT 2011


Jonathan M Davis Wrote:

> For instance, if I want to make it legal to pass a core.time.TickDuration to 
> to!(core.time.Duration) instead of casting it (which is actually why I've been 
> think of this issue), what is the standard way to do that? Or isn't there one? 
> I'm not aware of one. And if there isn't one, how should we do it?
> 
> I can think of 3 possible ways:
> 
> 1. Overload to in the module with the type being converted from. So, for 
> instance, core.time would have an overload for to which takes a TickDuration 
> and returns a Duration (either that or std.datetime if it didn't work to have 
> that in druntime for some reason). I'm not sure if that'll cause problems with 
> overload sets or not though.
> 
> 2. Make it so that std.conv.to can do its thing based on opCast. If a type 
> overloads opCast, then std.conv.to can use that opCast to do the conversion 
> (but only if opCast is defined, not for just any cast which may or may not be 
> valid).
> 
> 3. Make it so that user-defined types have a semi-standard member function 
> (e.g. to) which std.conv.to looks for and uses for conversions if it's there.
> 
> 
> Which of those would you consider to be the best? Or can you think of another, 
> better way? It seems to me that we need an essentially standard way of 
> defining conversions which use to. Otherwise, the only option is to use 
> opCast, and while there's nothing wrong with overloading opCast, it would 
> definitely be preferable to use to for safe conversions.
> 
> Thoughts?
> 
> - Jonathan M Davis

I'd also like to see a solution to this, primarily because std.conv.to is so useful. 

I don't think #1 works. At least, I've tried it and it gets confused on overloading. But maybe I didn't do it right. Along this same line, is there a way to write a ToImpl that std.conv can recognize? Again, I've tried this without success, but that doesn't mean it can't be done.

#2 is problematic because I might want to to! things I might not want to cast to. But it would be better than nothing.

I'd vote for #3. It's not much different than having std.conv look for a toString() function, which is great for to!string

In my case, I've created an alternative conversion module and only implemented the types I need; then I've added the types I defined. But I know this will bite me when I try to integrate with other modules.

I don't care much how this is implemented but it would be a very useful tool.

Paul


More information about the Digitalmars-d mailing list