我在理解D中的模板时遇到了一些麻烦。
我了解struct Foo(T) { }
类或函数的作用或等效作用,但是什么是作用template Bar(T) { }
?它与类,结构或函数模板有何不同?何时使用?
当您看到时template bar(T)
,您可以将其视为一个名称空间-类似于结构或类。就像一样struct Foo(T)
,内容当然是在template参数上模板化的,并且通常只能通过访问bar!T.memberName
。
我一般地说是因为有一些特殊规则。首先,我们有同名的模板。如果template foo(T)
具有与模板名称完全相同的成员,foo!T
则为的同义词foo!T.foo
,整个命名空间想法sorta消失。内部的其他成员foo!T
是隐藏的,无法访问。实际上,在编写时struct Foo(T) {}
,编译器会将其转换为template Foo(T) { struct Foo {} }
。
另一个特殊情况是mixin模板,基本上是片段,在实例化它们时将逐字删除它们。也就是说,此代码(请注意mixin
之前的关键字template
):
mixin template Foo() {
int i;
}
struct Bar {
mixin Foo!();
}
在功能上等同于以下代码:
struct Bar {
int i;
}
现在,为什么要使用just template
?首先是模板元编程。如果您查看std.traits
或std.meta
,这些模块将填充模板。不是混合模板,不是模板化的结构,类或函数,而是模板。它们对传递给它们的值和类型进行运算,并返回某种值或类型。
像这样使用的模板的一个非常简单的示例是std.meta.Reverse
。它接受一个参数列表并将其反转,如下所示:
template Reverse(TList...)
{
static if (TList.length <= 1)
{
alias Reverse = TList;
}
else
{
alias Reverse =
AliasSeq!(
Reverse!(TList[$/2 .. $ ]),
Reverse!(TList[ 0 .. $/2]));
}
}
您想使用模板的另一种情况是,在某些情况下应该删除模板类型。说你正在做你自己的Nullable(T)
,并且你希望Nullable!(Nullable!T)
永远成为自己Nullable!T
。如果您只是编写了代码struct Nullable(T) {}
,那么您将不会得到这种行为,并且最终会得到双可空类型。解决方案是使用模板约束:
struct Nullable(T) if (!isNullable!T) {}
和一个处理退化案例的模板:
template Nullable(T) if (isNullable!T) {
alias Nullable = T;
}
希望对您有所帮助,请询问是否有任何不清楚的地方。:)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句