digitalmars.D.learn - string, char[], overloaded functions.
- dajones (12/12) Oct 31 2014 Ok,
- Adam D. Ruppe (9/10) Oct 31 2014 Nope, char[] casting to string is generally a bad thing that
- ketmar via Digitalmars-d-learn (5/8) Oct 31 2014 On Sat, 01 Nov 2014 00:05:19 +0000
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (6/15) Nov 01 2014 No, it's `~=` that may or may not allocate, but `~` always does.
- ketmar via Digitalmars-d-learn (3/4) Nov 01 2014 you a right. sorry, i was wrong here.
- dajones (12/18) Nov 02 2014 I was using stdin.readln to read input from the console, and that takes ...
- Jonathan M Davis via Digitalmars-d-learn (43/55) Oct 31 2014 How could char[] implicitly convert to string? string is immutable(char)...
- dajones (7/81) Nov 02 2014 "Jonathan M Davis via Digitalmars-d-learn"
- Kagamin (2/5) Nov 01 2014 text(buf,"hoo")
- dajones (4/11) Nov 02 2014 Thanks!
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?
Oct 31 2014
On Friday, 31 October 2014 at 23:59:54 UTC, dajones wrote:So shouldnt char[] implicity convert to stringNope, char[] casting to string is generally a bad thing that should be avoided because it can leave you with a mutable string, which isn't supposed to happen. In your case, why are you using char[] for the buf instead of just string? BTW one could argue that char[] ~ operator should yield something that's implicitly convertable, since it allocates a new memory block anyway, but that's not how it works right now.
Oct 31 2014
On Sat, 01 Nov 2014 00:05:19 +0000 "Adam D. Ruppe via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> wrote:BTW one could argue that char[] ~ operator should yield something=20 that's implicitly convertable, since it allocates a new memory=20 block anyway, but that's not how it works right now.it's not necessarily allocates. but `(buf~"hoo").idup` does, so it can be used. ;-)
Oct 31 2014
On Saturday, 1 November 2014 at 03:28:36 UTC, ketmar via Digitalmars-d-learn wrote:On Sat, 01 Nov 2014 00:05:19 +0000 "Adam D. Ruppe via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> wrote:No, it's `~=` that may or may not allocate, but `~` always does. I think it's an instance of this bug [1]; `buf~"hoo"` should be inferred as unique, and therefore convert to `immutable`. https://issues.dlang.org/show_bug.cgi?id=1654BTW one could argue that char[] ~ operator should yield something that's implicitly convertable, since it allocates a new memory block anyway, but that's not how it works right now.it's not necessarily allocates. but `(buf~"hoo").idup` does, so it can be used. ;-)
Nov 01 2014
On Sat, 01 Nov 2014 08:36:40 +0000 via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:No, it's `~=3D` that may or may not allocate, but `~` always does.=20you a right. sorry, i was wrong here.
Nov 01 2014
"Adam D. Ruppe" <destructionator gmail.com> wrote in message news:xxnfghisussknbqzvopt forum.dlang.org...On Friday, 31 October 2014 at 23:59:54 UTC, dajones wrote:I was using stdin.readln to read input from the console, and that takes a char[] buffer. At least the example code on dlang.org reads into a char[] buffer. I want to coble together that char[] input with some string literals. I was writing a key to the registry like this... key.setValue("keyname", buf~"Foo"); but it kept saying it couldnt match setValue(string, int), which is one f the other overloads. Thanks, ChrisSo shouldnt char[] implicity convert to stringNope, char[] casting to string is generally a bad thing that should be avoided because it can leave you with a mutable string, which isn't supposed to happen. In your case, why are you using char[] for the buf instead of just string?
Nov 02 2014
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). - Jonathan M Davis
Oct 31 2014
"Jonathan M Davis via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> wrote in message news:mailman.1363.1414801299.9932.digitalmars-d-learn puremagic.com...On Friday, October 31, 2014 23:58:43 dajones via Digitalmars-d-learn wrote:My eyes were reading "immutable" but my brain was thinking "C++ const". Makes more sense now! Thanks, ChrisOk, 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).
Nov 02 2014
On Friday, 31 October 2014 at 23:59:54 UTC, dajones wrote:is there a better way than doing... cast(string)(buf~"hoo") to get it to pick the correct overload?text(buf,"hoo")
Nov 01 2014
"Kagamin" <spam here.lot> wrote in message news:lccftxangprboitrtvmh forum.dlang.org...On Friday, 31 October 2014 at 23:59:54 UTC, dajones wrote:Thanks! chrisis there a better way than doing... cast(string)(buf~"hoo") to get it to pick the correct overload?text(buf,"hoo")
Nov 02 2014