Nor*_*löw 2 generics d range palindrome dmd
在看过Andrei Alexandrescu的优秀的三个不太成功的D特征之后,我测试了如下所示的回文算法
import std.exception;
bool isPalindrome(T)(T[] a)
{
for (; a.length > 1; a = a[1 .. $-1]) {
if (a[0] != a[$-1]) {
return false;
}
}
return true;
}
bool isPalindrome(Range)(Range r)
{
for (; !r.empty; r.popFront(), r.popBack()) {
if (a.front != a.back) {
return false;
}
}
return true;
}
unittest {
enforce(isPalindrome("dallassallad"));
}
Run Code Online (Sandbox Code Playgroud)
数组版本在字符串上工作正常,但当我将范围版本添加到同一个编译单元DMD(2.062)抱怨时:
palindrome.d(31): Error: template palindrome.isPalindrome matches
more than one template declaration,
palindrome.d(10):isPalindrome(T)(T[] a) and
palindrome.d(20):isPalindrome(Range)(Range r)
Run Code Online (Sandbox Code Playgroud)
我的猜测是限制范围的使用不包括数组的情况.我怎么做?
我还测试了删除阵列版本,但后来我得到了错误
/home/per/Work/cognia/palindrome.d(22): Error: no property 'empty' for type 'string'
/home/per/Work/cognia/palindrome.d(22): Error: undefined identifier 'popFront'
/home/per/Work/cognia/palindrome.d(22): Error: undefined identifier 'popBack'
/home/per/Work/cognia/palindrome.d(23): Error: undefined identifier a, did you mean variable r?
/home/per/Work/cognia/palindrome.d(23): Error: undefined identifier a, did you mean variable r?
/home/per/Work/cognia/palindrome.d(27): Warning: statement is not reachable
/home/per/Work/cognia/palindrome.d(31): Error: template instance palindrome.isPalindrome!(string) error instantiating
Run Code Online (Sandbox Code Playgroud)
我似乎范围版本不适用于我觉得奇怪的数组.
该怎么办?
将模板约束添加到第二个模板,如下所示:
bool isPalindrome(Range)(Range r)
if (!isArray!Range)
Run Code Online (Sandbox Code Playgroud)
您将需要导入std.traits
的isArray
模板.
如果你希望只使用第二个模板,你将不得不进口std.array
其采用UFCS
(统一函数调用语法),以使阵列有front
,popFront
,empty
,等功能.
UFCS基本上意味着:
int[] x;
int f = x.front;
Run Code Online (Sandbox Code Playgroud)
被翻译成:
int f = front(x);
Run Code Online (Sandbox Code Playgroud)
front
和其他数组定义为数组std.array
,这使您可以像使用数组一样使用数组.您可以为自己的类型使用相同的技术.您可以定义范围函数,例如front
在struct/class中,或者您可以在外部将它们定义为将struct/class作为其第一个参数的函数.
有关详细信息,请参阅std.range的文档.
另请注意,通用版本中存在一个令人尴尬的错误,因为它可能会尝试减少空白范围.更正后的版本是:
bool isPalindrome(Range)(Range r)
{
while (!r.empty) {
if (a.front != a.back) {
return false;
}
r.popFront();
if (r.empty) {
return true;
}
r.popBack();
}
return true;
}
Run Code Online (Sandbox Code Playgroud)