digitalmars.D.learn - Using replaceInPlace, string and char[]
- TSalm (41/41) Aug 15 2015 Hi,
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (27/33) Aug 15 2015 This looks like a bug to me. The template constraints of the two
- TSalm (18/54) Aug 15 2015 Yes I understand. I've used ldc2. With DMD (v0.067.1) the error
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (10/15) Aug 15 2015 Right ?
- TSalm (3/5) Aug 16 2015 :-)
Hi, A newbie question : I wrote this simple code : import std.array; import std.stdio; void main() { char[] a = "mon texte 1".dup; char[] b = "abc".dup; size_t x = 4; size_t y = 9; replaceInPlace( a, x , y, b ); writeln( a ); } But compilation fails : /usr/include/dmd/phobos/std/array.d(2052): Error: template std.algorithm.remove cannot deduce function from argument types !()(char[], Tuple!(immutable(uint), uint)), candidates are: /usr/include/dmd/phobos/std/algorithm.d(8542): std.algorithm.remove(SwapStrategy s = SwapStrategy.stable, Range, Offset...)(Range range, Offset offset) if (s != SwapStrategy.stable && isBidirectionalRange!Range && hasLvalueElements!Range && hasLength!Range && Offset.length >= 1) /usr/include/dmd/phobos/std/algorithm.d(8623): std.algorithm.remove(SwapStrategy s = SwapStrategy.stable, Range, Offset...)(Range range, Offset offset) if (s == SwapStrategy.stable && isBidirectionalRange!Range && hasLvalueElements!Range && Offset.length >= 1) /usr/include/dmd/phobos/std/algorithm.d(8757): std.algorithm.remove(alias pred, SwapStrategy s = SwapStrategy.stable, Range)(Range range) if (isBidirectionalRange!Range && hasLvalueElements!Range) inout.d(13): Error: template instance std.array.replaceInPlace!(char, char[]) error instantiating Don't understand why this doesn't work: it compiles fine and runs perfectly if I change "char[]" by "string" ... don't understand why since the documentation says : String literals are immutable (read only). How this function can change a type that is immutable ? Thanks for your help. TSalm
Aug 15 2015
This looks like a bug to me. The template constraints of the two overloads are pretty complicated. This case should match only one of them. On 08/15/2015 12:43 AM, TSalm wrote:Don't understand why this doesn't work: it compiles fine and runs perfectly if I change "char[]" by "string"You mean, this: import std.array; import std.stdio; void main() { string a = "mon texte 1"; // <-- now string writeln(a.ptr); // added char[] b = "abc".dup; size_t x = 4; size_t y = 9; replaceInPlace( a, x , y, b ); writeln( a ); writeln(a.ptr); // added } The output: 4BC480 mon abc 1 7FC2AB867210 <-- different... don't understand why since the documentation says : String literals are immutable (read only). How this function can change a type that is immutable ?It cannot change the characters of the original string. replaceInPlace takes its first parameter by reference. What changes is 'a' itself. As evidenced by the output of the program, 'a' is now a slice to a new set of immutable characters. If there were other slices to "mon texte 1", they wouldn't see a change. Ali
Aug 15 2015
On Saturday, 15 August 2015 at 08:07:43 UTC, Ali Çehreli wrote:This looks like a bug to me. The template constraints of the two overloads are pretty complicated. This case should match only one of them.Yes I understand. I've used ldc2. With DMD (v0.067.1) the error is more clear : inout.d(11): Error: std.array.replaceInPlace called with argument types (char[], uint, uint, char[]) matches both: /usr/include/dmd/phobos/std/array.d(2214): std.array.replaceInPlace!(char, char[]).replaceInPlace(ref char[] array, uint from, uint to, char[] stuff) and: /usr/include/dmd/phobos/std/array.d(2247): std.array.replaceInPlace!(char, char[]).replaceInPlace(ref char[] array, uint from, uint to, char[] stuff) Must create a ticket for it ?Yes I understand, thanks. In the other hand using "string" is not efficient since this certainly make a copy of the original string. Right ? This is better to use "replaceInPlace" with "char[]", but this doesn't actually work :-(Don't understand why this doesn't work: it compiles fine andrunsperfectly if I change "char[]" by "string"You mean, this: import std.array; import std.stdio; void main() { string a = "mon texte 1"; // <-- now string writeln(a.ptr); // added char[] b = "abc".dup; size_t x = 4; size_t y = 9; replaceInPlace( a, x , y, b ); writeln( a ); writeln(a.ptr); // added } The output: 4BC480 mon abc 1 7FC2AB867210 <-- different... don't understand why since the documentation says : String literals are immutable (read only). How this function can change a type that is immutable ?It cannot change the characters of the original string. replaceInPlace takes its first parameter by reference. What changes is 'a' itself. As evidenced by the output of the program, 'a' is now a slice to a new set of immutable characters. If there were other slices to "mon texte 1", they wouldn't see a change.
Aug 15 2015
On 08/15/2015 01:47 AM, TSalm wrote:Must create a ticket for it ?I think so. Unless others object in 10 minutes... :)In the other hand using "string" is not efficient since this certainly make a copy of the original string.Right ?This is better to use "replaceInPlace" with "char[]", but this doesn't actually work :-(There is probably a workaround, which others will hopefully show. (I have to leave now. :) ) However, although not in your example, replaceInPlace would still copy if the result would not fit in the original char[]. Hm... Come to think of it, it cannot replace in place anyway, unless it knows that the slice is the only one looking at those characters. Otherwise, you would disturbing your other slices. (?) Ali
Aug 15 2015
:-) Done : https://issues.dlang.org/show_bug.cgi?id=14925 Thanks for your helpMust create a ticket for it ?I think so. Unless others object in 10 minutes... :)
Aug 16 2015