为什么std.algorithm.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!(范围)&

如果我尝试使用std.algorithm.fill(Range1,Range2)(Range1 range,Range2 filler),我会不断收到错误消息,即找不到模板匹配。看起来编译器正在尝试匹配fill(范围、值),而不是另一个

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
。这是因为它们都是unicode
char
是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