On Tuesday, 4 November 2014 at 02:49:55 UTC, Steven Schveighoffer
wrote:
On 11/3/14 6:05 PM, Jonathan Marler wrote:
In many cases templates are good because they provide the a
way for the
programmer to use a library optimized for their particular
application.
This is the case for the toString function. An argument can
be made
that using templates is dangerous because if they are used
incorrectly,
the number of template instantiates can blow up. But this can
always be
solved by the programmer by changing all their template calls
to use the
same template parameters. This allows the template solution to
simultaneously support a sink that represents a real function,
or a
delegate, or whatever the application needs.
If we make toString a template, we precludes it as a virtual
function, and we force the object to expose its inner workings.
I think the template solution has advantages, one being the
possibility for optimization. But I don't think the gains are
significant enough. It's also more complex than necessary.
I was thinking you could have the best of both worlds with
templates. For example, you could define the toString template
like this:
void toStringTemplate(T)(T sink)
if(isOutputRange!(T,const(char)[]))
Then you could declare an alias like this:
alias toString = toStringTemplate!(void
delegate(const(char)[]));
Which (correct me if I'm wrong) I believe is equivalent to the
original sink delegate function. This allows programmers to
write the logic for toString once and allow a developer using the
library to choose whether they want to use the delegate version
or the generic output range version.
This gives the user of the library the ability to choose the best
version for their own application.
Note: I added this "alias" method to my dtostring.d test code and
it wasn't as fast as the delegate version. I'm not sure why as I
thought the generated code would be identical. If anyone has any
insight as to why this happened let me know.
code is at http://marler.info/dtostring.d