我在D中有一个模板化的类,它将另一个模板作为参数,因此它开始:
class RuleVars(alias RuleType, RuleRange, SubstitutionRange)
if (__traits(isTemplate, RuleType)) {
import std.range.primitives;
import std.traits;
import Capsicum.PatternMatching.Engine;
private {
static if (isAssociativeArray!RuleRange) {
alias RuleType = ElementType!(typeof(ruleRange.values));
} else {
alias RuleType = ElementType!RuleRange;
}
static if (isAssociativeArray!SubstitutionRange) {
alias SubstitutionType = ElementType!(typeof(ruleRange.values));
} else {
alias RuleType = ElementType!RuleRange;
}
alias MatchingPolicy = RuleType!(Element, RuleElement);
...
需要注意的重要一点是,如果RuleType不是模板,则该类将无法实例化。 作为必要,我有一个函数可以创建这个类的实例:
RuleVars!(RuleType, RuleRange, SubstitutionRange) CreateRuleVars(alias RuleType, RuleRange, SubstitutionRange)(RuleRange leftHandSide, SubstitutionRange rightHandSide) {
return new RuleVars!(RuleType, RuleRange, SubstitutionRange)(leftHandSide, rightHandSide);
}
但是,当我尝试像这样设置类时:
CreateRuleVars!UnboundRules([0 : 'a', 2 : 'b', 4 : 'a', 6 : 'b'],
[1 :'a', 3 : 'a', 4 : 'b', 6 : 'b'])
我收到以下错误:
source\Capsicum\PatternMatching\RuleSet.d(25,26): Error: template instance RuleType!(Element, RuleElement) RuleType is not a template declaration, it is a alias
source\Capsicum\PatternMatching\RuleSet.d(73,1): Error: template instance Capsicum.PatternMatching.RuleSet.RuleVars!(UnboundRules, char[int], char[int]) error instantiating
source\Capsicum\PatternMatching\RuleSet.d(127,31): instantiated from here: CreateRuleVars!(UnboundRules, char[int], char[int])
它抱怨这条特定的路线:
alias MatchingPolicy = RuleType!(Element, RuleElement);
这里传递的特定模板被证明在自己使用和实例化时可以工作,所以它应该不是问题。它显然也是一个模板,否则模板参数匹配就会失败。官方D文章显示模板可以作为模板参数传递,如下所示:
class Foo(T, alias C)
{
C!(T) x;
}
据我所知,我正确地做到了。有什么想法吗?
答案 0 :(得分:3)
问题是这些问题:
alias RuleType = ElementType!(typeof(ruleRange.values));
您重新定义隐藏参数的本地符号RuleType
,因此后续行指的是该本地别名,而不是您要使用的参数。
现在,有趣的是,这可能是编译器中的诊断错误。如果你使用常规参数做类似的事情:
void main(string[] args) {
int args;
}
编译器将标记它:
Error: variable args is shadowing variable aa.sub.main.args
因为这几乎肯定是一个错误;你肯定打算使用两个单独的名称,所以你仍然可以引用参数(否则你只能引用局部变量!)。但似乎编译器没有对模板参数进行这样的测试。