为什么std.algorithm.fill不接受字符数组?

时间:2011-06-19 08:31:20

标签: d

如果我尝试使用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 [])

2 个答案:

答案 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是有效字符。然而,charwchar本身保证是有效字符,如果您看到个人char或{{}},则通常会出现错误已使用{1}}。通常必须合并多个wcharchars才能构成一个字符。因此,无法单独处理wcharschars。这就是为什么如果你用foreach迭代任何类型的字符串,你应该始终将其类型命名为wchars

dchar

如果你没有指定foreach(dchar c; str) ... ,那么它就是dchar的字符类型,除非strstr的数组,否则它总是会导致错误因为你最终会得到代码单元(字符片段)而不是代码点(整个字符)。只能单独处理dchar

正因为如此,所有字符串类型和字符数组都被认为是dchars的范围,而不管它们的实际元素类型是什么。因此,当您在字符串上调用dchar时,它可能会弹出比popFrontchar更多的内容。如果您拨打wchar,可能需要解码多个frontchars才能返回字符串中第一个字符wchars。这意味着您无法将dcharchar数组视为随机访问。第四个字符可能是第四个元素,也可能是第12个元素。无论它从哪个索引开始,它可能是多个代码单元长,因此您不能只抓取wcharchar数组中的随机索引并期望它有效。因此,wcharchar的数组是随机访问范围。它们也不是输出范围。

想一想。我们以字符wchar'\U00010143')为例。它的代码单元长度为4(UTF-8)和2(UTF-16)。您不能随意填充任何随机char数组。如果它是wchar数组,并且其长度不是4的倍数,那么最后一个(char)将不适合。如果它是数组,并且其长度不是2的倍数,那么它将具有相同的问题。因此,在wcharfill数组上使用char之类的函数确实无效。

现在,使用wchar数组可以正常工作。由于保证UTF-32代码单元是代码点,因此dchar数组中的每个字符都是一个元素,它既可以是随机访问范围,也可以是输出范围。因此,如果要将dchar之类的函数用于字符数组,则需要使用fill数组。您可以使用dchar将其转换为之后所需的字符数组类型,但无法直接填充std.conv.tochar数组。

wcharchar的数组非常适用于不需要输出范围或随机访问范围的算法,但它们不适用于那些。对于那些,您需要wchar的数组。

答案 1 :(得分:2)

因为typeof(test.front)== dchar,而不是char

这可能是一个错误,但这是因为typeof(test.front)dchar,而不是char,因为它被解释为UTF-8字符串并且它为您提供了第一个Unicode字符,而不是比第一个char

为什么是这样解释的?

您的import之一可能直接或间接导入了std.array(或某种类似的)模块,front()函数返回dchar char[] {1}}。尝试找出它是哪一个,而不是使用它,而是做import std.iterator;那个人返回char而不是dchar