3
/** This is struct S. */
struct S(T) {

  static if(isFloatingPoint!T)
  {
    /// This version works well with floating-point numbers.
    void fun() { }
  }
  else
  {
    /// This version works well with everything else.
    void fun() { }
    /// We also provide extra functionality.
    void du() { }
  }
}

使用 编译dmd -D,仅为第一个块生成文档。我如何让它也为else块生成?

4

1 回答 1

3

对于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),你将不得不单独生成你的文档正常构建。

于 2012-09-22T18:56:20.247 回答