如http://dlang.org/template.html的参数推导部分所述,推导模板参数的类型时:
- 如果参数没有类型特化,则参数的类型设置为模板实参。
- 如果类型特化依赖于类型参数,则该参数的类型设置为类型参数的对应部分。
- 如果在检查了所有类型参数之后,还有任何类型参数没有分配类型,则为它们分配与 TemplateArgumentList 中相同位置的模板参数相对应的类型。
- 如果应用上述规则并没有为每个模板参数生成一种类型,那么它就是一个错误。
与您的情况相对应的示例是:
template TBar(T : T*) { }
alias TBar!(char*) Foo3; // (2) T is deduced to be char
因此,您在第一个示例中看到的是预期行为。因为T
两边都是,所以T
最终被评估为模板参数的结果T*
。因此,由于模板参数是int*
,T*
将会是int*
,并且T
最终是int
。您所拥有的与以下内容非常相似std.traits.pointerTarget
:
/**
Returns the target type of a pointer.
*/
template pointerTarget(T : T*)
{
alias T pointerTarget;
}
您的第二个示例编译,因为该模板要求它T
可以隐式转换为int*
. 并且由于int*
可以隐式转换为自身,因此当您int*
作为模板参数传递时,它可以工作。给你带来麻烦的是when T
is on both,因为表达式的右边依赖于左边。
现在,我假设您实际上打算在这里测试的是模板参数是一个指针?如果是这种情况,那么您应该使用std.traits.isPointer
:
struct S(T)
if(isPointer!T)
{
T t;
}