对于version块,它只是最终在文档中使用的版本(无论是第一个还是最后一个或两者之间的任何一个)。因此,例如,如果您有一个version用于 Linux 的块和一个用于 Windows 的块,那么只有与您编译的系统匹配的块才会出现在文档中。
static if模板之外的块似乎以相同的方式运行。如果它们被编译进去,那么它们的 ddoc 注释最终会出现在文档中,而如果它们没有被编译进去,它们就不会。
但是,模板中static if的块似乎总是从第一个静态 if 块中获取文档,即使它总是. 但是考虑到这些静态 if 最终可能同时是and (来自模板的不同实例化),并且编译器实际上并不要求实例化模板以使其 ddoc 注释最终出现在生成的文档中,这是有道理的。它没有像模板之外的块那样的正确答案。falsetruefalsestatic if
无论如何,将文档放在version块或中通常是一个坏主意static if,正是因为它们正在使用条件编译并且可能会或可能不会被编译。解决方案是使用version(D_Ddoc)块。所以,你最终会得到这样的东西:
/// This is struct S
struct S(T)
{
version(D_Ddoc)
{
/// Function foo.
void fun();
/// Extra functionality. Exists only when T is not a floating point type.
void du();
}
else
{
static if(isFloatingPoint!T)
void fun() { }
else
{
void fun() { }
void du() { }
}
}
}
我还要注意,即使您尝试做的事情奏效了,它在文档中看起来也很奇怪,因为您最终会foo在那里两次使用完全相同的签名但不同的评论。static if根本不会出现在文档中,因此无法知道在什么情况下foo存在。它看起来就像你以某种方式声明foo了两次。
这种情况与模板约束类似。约束不会出现在文档中,因此当您处理仅由其约束重载的模板化函数时,记录每个函数重载是没有意义的。
但是,您不需要version(D_Ddoc)的一个地方是,当您在一系列version块中具有相同的功能时。例如
/// foo!
version(linux)
void foo() {}
else version(Windows)
void foo() {}
else
static assert(0, "Unsupported OS.");
version无论在哪个块中编译,ddoc 注释都将最终出现在生成的文档中。
应该注意的是,version(D_Ddoc)块的使用往往会使得在使用时-D,除了生成文档之外编译你的代码是没有意义的,并且你运行的实际可执行文件应该由一个单独的构建生成,它不'不使用-D。您可以将完整的代码放在version(D_Ddoc)块中以避免这种情况,但这意味着重复代码,并且它实际上不适用于static if. Phobos 使用version(StdDdoc)(它为自己定义)而不是version(D_Ddoc)这样,如果你不使用version(D_Ddoc)块,你仍然可以编译-D并让 Phobos 工作,但是一旦你开始使用version(D_Ddoc),你将不得不单独生成你的文档正常构建。