为什么std.algorithm.fill不接受字符数组?
如果我尝试使用std.algorithm.fill(Range1,Range2)(Range1 range,Range2 filler),我会不断收到错误消息,即找不到模板匹配。看起来编译器正在尝试匹配fill(范围、值),而不是另一个为什么std.algorithm.fill不接受字符数组?,d,D,如果我尝试使用std.algorithm.fill(Range1,Range2)(Range1 range,Range2 filler),我会不断收到错误消息,即找不到模板匹配。看起来编译器正在尝试匹配fill(范围、值),而不是另一个 auto test = new char[256]; fill(test, "abc".dup); 无法使用fill填充字符数组吗 错误 test.d(13):错误:模板 标准算法填充(范围、值) (isForwardRange!(范围)&
auto test = new char[256];
fill(test, "abc".dup);
无法使用fill填充字符数组吗
错误
test.d(13):错误:模板
标准算法填充(范围、值)
(isForwardRange!(范围)&&
是(typeof(range.front=filler)),是
不匹配任何函数模板
声明
测试d(13):错误:
模板
标准算法填充(范围、值)
(isForwardRange!(范围)&&
is(类型(range.front=filler)))
无法从中推断t模板函数
参数类型!()(字符[],字符[])
因为typeof(test.front)==dchar,而不是char
这可能是一个错误,但这是因为typeof(test.front)
是dchar
,而不是char
,因为它被解释为一个UTF-8字符串,它给你第一个Unicode字符,而不是第一个char
foreach(dchar c; str)
...
但为什么会这样解释呢?
您的一个
导入
可能直接或间接导入了一个模块,如std.array
(或类似的模块),其front()
函数为char[]
返回dchar
。尝试找出它是哪一个,而不是使用它,而是使用import std.iterator
;返回的是char
,而不是dchar
std.algorithm。fill
取一个范围。所有字符串类型的范围均为dchar
。这是因为它们都是unicodechar
是UTF-8编码单元wchar
是UTF-16编码单元,dchar
是UTF-32编码单元。多个代码单元组成一个代码点,即字符。对于UTF-8,一个代码点最多可以有6个代码单元。对于UTF-16,它最多可以是2个。对于UTF-32,1个代码单元始终是1个代码点,因此dchar
始终保证为有效字符<但是,code>char和wchar
本身并不保证是有效字符,如果您看到使用了单个char
或wchar
,则通常是一个错误。多个字符
或wchars
通常必须组合成一个字符。因此,您不能单独处理chars
或wchars
。这就是为什么如果使用foreach对任何类型的字符串进行迭代,都应该将其类型指定为dchar
foreach(dchar c; str)
...
如果您没有指定dchar
,那么它将是str
的任何字符类型,这将不可避免地导致错误,除非str
是dchar
的数组,因为您最终得到的是代码单元(字符片段)而不是代码点(整个字符)。只有dchars
可以单独处理
正因为如此,所有字符串类型和字符数组都被认为是dchar
的范围,而不管它们的实际元素类型是什么。因此,当您在字符串上调用popFront
时,它可能会弹出比一个char
或wchar
更多的内容。如果调用front
,它可能需要解码多个char
或wchars
以返回字符串中的第一个字符dchar
。这意味着您不能将char
或wchar
数组视为随机访问。第四个字符可以是第四个元素,也可以是第十二个。不管它从哪个索引开始,它都可能有多个代码单元长,所以你不能在char
或wchar
数组中随机获取一个索引并期望它是有效的。因此,char
和wchar
的数组不是随机访问范围。它们也不是输出范围
想想看。让我们以字符
'\U00010143'
(不再有std.iterator了。我相信它是在dmd的最新版本中错误发布的,但它已被弃用并删除。它不再在Phobos中。我了解代码单元与代码点的关系,但我并不总是清楚谁对数据完整性负责。例如,removechars坚持receiving字符串,甚至不接受dstring。所以我想,我可以负责填充函数。char[]没有包含任何多字节字符。我本可以猜到这与编码有关,但错误消息让我困惑。感谢您的背景。查看removechars
,它似乎应该与dstring
(尽管出于某种原因,它不会接受字符串和模式的不同字符串类型,这可能是造成问题的原因)。但Phobos中没有基于范围的函数会将char
或wchar
数组视为char
或wchar
的一个范围,而且数量不多(如果有的话)这将真正将它们视为char
或wchar
的数组。某些函数将具有专门化,可以利用它们是数组这一事实,但前提是安全且不会出现编码问题。对,只要模式类型匹配,removechars实际上会接受任何字符串。这是有意义的。但它将l接受char[],而fill不会。我想这是因为removechars知道输入将转换为dchar[],而fill不能做出这样的假设并为您执行此操作。removechars
并没有更改原始字符串。它正在分配一个新字符串,这样它就可以使其具有适当的长度,并且不必担心更改任何内容,因此它可以处理任何字符类型,而fill
必须更改已使用的数组由于它已被禁用,因此无法使用char
或wchar
。