string, char[], overloaded functions.

dajones via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Nov 2 16:52:06 PST 2014


"Jonathan M Davis via Digitalmars-d-learn" 
<digitalmars-d-learn at puremagic.com> wrote in message 
news:mailman.1363.1414801299.9932.digitalmars-d-learn at puremagic.com...
> On Friday, October 31, 2014 23:58:43 dajones via Digitalmars-d-learn 
> wrote:
>> Ok,
>>
>> void Foo(string name, string value);
>> void Foo(string name, int value);
>>
>> then...
>>
>> char[] buf = "woo".dup;
>> Foo("bar","woohoo"); // works ok
>> Foo("bar",buf~"hoo"); // fails, error says cant match params (string, 
>> int)
>>
>> So shouldnt char[] implicity convert to string, and hence match the
>> (string,string) parameter list?
>>
>> is there a better way than doing...
>>
>> cast(string)(buf~"hoo")
>>
>> to get it to pick the correct overload?
>
> How could char[] implicitly convert to string? string is 
> immutable(char)[], so
> its elements can't be changed, whereas char[]'s can be. So, if char[]
> implicitly converted to immutable(char)[], either it would be by casting 
> and
> make it possible to violate the immutability of the characters (because
> something could change the original char[] array, and then affect the
> supposedly immutable characters in the one that came from the cast), or it
> would be doing idup for you, which would then be an invisible allocation 
> and
> potential performance hit.
>
> string and char[] will implicitly convert to const(char)[], but mutable 
> types
> don't generally implicitly convert to immutable ones, immutable ones don't
> implicitly convert to mutable ones, and const doesn't implicitly convert 
> to
> either.
>
> The reason that "woohoo" works is because string literals are strings, not
> char[]. In the case of, buf ~ "hoo", it generates a new char[] with the
> elements of buf and "hoo", because buf was char[], not string, and char[]
> isn't implicitly convertible to either string or int.
>
> If you want a function to take any type of mutability for strings, then 
> you
> can use const:
>
> void foo(const(char)[] name const(char)[] value);
>
> though that has the downside of making it so that you're stuff using 
> const,
> which is particularly annoying if the function returns
>
> const(char)[] foo(const(char)[] name const(char)[] value);
>
> To fix that, you can use inout
>
> inout(char)[] foo(inout(char)[] name inout(char)[] value);
>
> so that the constness stays the same, but then the constness would have to
> match in this case, because there are two inout parameters. If you want to
> accept any constness without dealing with inout and without having to use
> const, then you can just templatize the function, e.g.
>
> C[] foo(C, D)(C[] name, D[] value)
>    if(is(C == char) && is(D == char))
>
> and to accept any character type, you could do something like
>
> C[] foo(C, D)(C[] name, D[] value)
>    if(isSomeChar!C && isSomeChar!D)
>
> but obviously that gets more complicated.
>
> In any case, the only type of argument that will be accepted for a string
> parameter is string, not char[] or const(char)[], and casting to string 
> from
> char[] will violate the type system if any other references to that same 
> array
> exist (making it possible for the supposedly immutable chars to be 
> mutated).
> So, you should use either idup or to!string() (the advantage of 
> std.conv.to
> being that if the argument ever changed to string, no copy would be made,
> whereas idup would still make a copy).

My eyes were reading "immutable" but my brain was thinking "C++ const". 
Makes more sense now!

Thanks,

Chris




More information about the Digitalmars-d-learn mailing list