如果我尝试使用std.algorithm.fill(Range1,Range2)(Range1范围,Range2填充),我会不断收到错误消息,表明找不到模板匹配。看起来编译器试图匹配fill(Range,Value)而不是另一个。
auto test = new char[256];
fill(test, "abc".dup);
是否无法使用fill填充字符数组?
错误
test.d(13):错误:模板 std.algorithm.fill(Range,Value)if (isForwardRange!(范围)&& 是(typeof(range.front = filler))) 不匹配任何功能模板 声明
test.d(13):错误: 模板 std.algorithm.fill(Range,Value)if (isForwardRange!(范围)&& 是(typeof(range.front = filler))) 不能从中推断出来的功能 参数类型!()(char [],char [])
答案 0 :(得分:8)
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
是有效字符。然而,char
和wchar
本身不保证是有效字符,如果您看到个人char
或{{}},则通常会出现错误已使用{1}}。通常必须合并多个wchar
或chars
才能构成一个字符。因此,无法单独处理wchars
或chars
。这就是为什么如果你用foreach迭代任何类型的字符串,你应该始终将其类型命名为wchars
。
dchar
如果你没有指定foreach(dchar c; str)
...
,那么它就是dchar
的字符类型,除非str
是str
的数组,否则它总是会导致错误因为你最终会得到代码单元(字符片段)而不是代码点(整个字符)。只能单独处理dchar
。
正因为如此,所有字符串类型和字符数组都被认为是dchars
的范围,而不管它们的实际元素类型是什么。因此,当您在字符串上调用dchar
时,它可能会弹出比popFront
或char
更多的内容。如果您拨打wchar
,可能需要解码多个front
或chars
才能返回字符串中第一个字符wchars
。这意味着您无法将dchar
或char
数组视为随机访问。第四个字符可能是第四个元素,也可能是第12个元素。无论它从哪个索引开始,它可能是多个代码单元长,因此您不能只抓取wchar
或char
数组中的随机索引并期望它有效。因此,wchar
和char
的数组是不随机访问范围。它们也不是输出范围。
想一想。我们以字符wchar
('\U00010143'
)为例。它的代码单元长度为4(UTF-8)和2(UTF-16)。您不能随意填充任何随机或
char
数组。如果它是wchar
数组,并且其长度不是4的倍数,那么最后一个(char
)将不适合。如果它是数组,并且其长度不是2的倍数,那么它将具有相同的问题。因此,在
wchar
或fill
数组上使用char
之类的函数确实无效。
现在,使用wchar
数组可以正常工作。由于保证UTF-32代码单元是代码点,因此dchar
数组中的每个字符都是一个元素,它既可以是随机访问范围,也可以是输出范围。因此,如果要将dchar
之类的函数用于字符数组,则需要使用fill
数组。您可以使用dchar
将其转换为之后所需的字符数组类型,但无法直接填充std.conv.to
或char
数组。
wchar
和char
的数组非常适用于不需要输出范围或随机访问范围的算法,但它们不适用于那些。对于那些,您需要wchar
的数组。
答案 1 :(得分:2)
这可能是一个错误,但这是因为typeof(test.front)
是dchar
,而不是char
,因为它被解释为UTF-8字符串并且它为您提供了第一个Unicode字符,而不是比第一个char
。
您的import
之一可能直接或间接导入了std.array
(或某种类似的)模块,front()
函数返回dchar
char[]
{1}}。尝试找出它是哪一个,而不是使用它,而是做import std.iterator
;那个人返回char
而不是dchar
。