Semantics of toString

Steven Schveighoffer schveiguy at yahoo.com
Thu Nov 12 12:34:08 PST 2009


On Thu, 12 Nov 2009 14:40:12 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail at erdani.org> wrote:

> Steven Schveighoffer wrote:
>> On Thu, 12 Nov 2009 13:46:08 -0500, Andrei Alexandrescu  
>> <SeeWebsiteForEmail at erdani.org> wrote:
>>
>>>>   From my C++ book, it appears to only use virtual inheritance.  I  
>>>> don't know enough about virtual inheritance to know how that changes  
>>>> function calls.
>>>>  As far as virtual functions, only the destructor is virtual, so  
>>>> there is no issue there.
>>>
>>> You're right, but there is an issue because as far as I can recall  
>>> these functions' implementation do end up calling a virtual function  
>>> per char; that might be streambuf.overflow. I'm not keen on  
>>> investigating this any further, but I'd be grateful if you shared any  
>>> related knowledge.
>>  Yep, you are right.  It appears the reason they do this is so the  
>> conversion to the appropriate width can be done per character (and is a  
>> no-op for char).
>>
>>> At the end of the day, there seem to be violent agreement that we  
>>> don't want one virtual call per character or one delegate call per  
>>> character.
>>  After running my tests, it appears the virtual call vs. delegate is so  
>> negligible, and the virtual call vs. direct call is only slightly less  
>> negligible, I think the virtualness may not matter.  However, I think  
>> avoiding one *call* per character is a worthy goal.
>>  This doesn't mean I change my mind :)  I still think there is little  
>> benefit to having to conjure up an entire object just to convert  
>> something to a string vs. writing a simple inner function.
>>  One way to find out is to support only char[], and see who complains  
>> :)  It'd be much easier to go from supporting char[] to supporting all  
>> the widths than going from supporting all to just one.
>
> One problem I just realized is that, if we e.g. offer only put(in  
> char[]) or a delegate to that effect, we make it impossible to output  
> one character efficiently. The (&c)[0 .. 1] trick will not work in safe  
> mode. You'd have to allocate a one-element array dynamically.

char[1] buf;
buf[0] = c;
put(buf);

Although it would be a useful feature to be able to convert a value type  
to an array of one element reference, especially since that should be as  
safe as taking a slice of a static array.

Another solution, although I'm unaware of the added costs:

void toString(void delegate(in char[]...) put, string fmt);

> Also, many OSs adopted UTF-16 as their standard format. It may be wise  
> to design for compatibility.

So you want toString's to look like this?

version(utf16isdefault)
{
   textobj.put("Array: "w);
   ...
}
else
{
   textobj.put("Array: ");
   ...
}

-Steve



More information about the Digitalmars-d mailing list