无法解析模板功能的类型

Yuu*_*shi 2 templates d phobos

我正在尝试在D中编写非常简单的代码,但是我遇到了一个标准库模板函数(特别是nextPermutation来自std.algorithm)的问题.

我正在尝试做的关键是创建pandigital数字的所有排列(即,包括所有值1到9的数字恰好一次).

为此,我做了以下事情:

import std.algorithm;
import std.conv;

int[] pandigitals()
{
    char[] initial = "123456789".dup;
    auto pan = [to!int(initial)];
    while(nextPermutation!(initial)) {
       pan ~= to!int(initial);
    }
    return pan;
}
Run Code Online (Sandbox Code Playgroud)

这给了我错误:

错误:无法解析nextPermutation的类型!(初始)

我也尝试过显式设置类型:

while(nextPermutation!("a<b", char[])(initial))
Run Code Online (Sandbox Code Playgroud)

但是,这会给出一个错误,说它与模板不匹配:

错误:模板实例std.algorithm.nextPermutation( "A <B",CHAR [])不匹配,如果(isBidirectionalRange BidirectionalRange模板声明nextPermutation(别名更少= "A <B",BidirectionalRange)(参考文献BidirectionalRange范围)&&! hasSwappableElements!BidirectionalRange)

呼叫的正确形式是什么?

Jon*_*vis 5

好吧,你的第一个问题是你initial作为模板参数而不是函数参数传递.该!()是模板参数.所以,而不是

while(nextPermutation!(initial))
Run Code Online (Sandbox Code Playgroud)

你需要做的

while(nextPermutation(initial)) {
Run Code Online (Sandbox Code Playgroud)

现在,这仍然会给你一个错误.

q.d(10): Error: template std.algorithm.nextPermutation cannot deduce function from argument types !()(char[]), candidates are:
/usr/include/D/phobos/std/algorithm.d(12351):        std.algorithm.nextPermutation(alias less = "a<b", BidirectionalRange)(ref BidirectionalRange range) if (isBidirectionalRange!BidirectionalRange && hasSwappableElements!BidirectionalRange)
Run Code Online (Sandbox Code Playgroud)

这是因为hasSwappableElements!(char[])false,并且每个nextPermutations'模板约束它需要true一个类型才能使用nextPermutations.

这是false因为所有字符串都被视为范围dchar而不是它们的实际元素类型.这是因为在UTF-8(char)和UTF-16(wchar)中,每个代码点有多个代码单元,因此对单个代码单元进行操作可能会破坏代码点,而在UTF-32(dchar)中,总会有一个代码每个代码点的单位.从本质上讲,如果阵列char或者wchar被作为治疗范围char或者wchar,你会跑分手字符的高风险,使你与人物的作品,而不是整个字符结束.所以,一般来说在D中,如果你想对一个角色进行操作,你应该使用dchar,而不是charwchar.如果你不是很熟悉的Unicode,我建议你阅读这篇文章由Joel Spoelsky关于这个问题的.

然而,无论原因hasSwappableElements!(char[])false,它 false,那么你将需要使用不同的类型.最简单的事情可能是将算法交换为使用dchar[]而不是.

int[] pandigitals()
{
    dchar[] initial = "123456789"d.dup;
    auto pan = [to!int(initial)];
    while(nextPermutation(initial)) {
       pan ~= to!int(initial);
    }
    return pan;
}
Run Code Online (Sandbox Code Playgroud)