如果有`静态if`,如何生成文档

时间:2012-09-22 18:22:38

标签: d

/** 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块生成?

1 个答案:

答案 0 :(得分:3)

对于version块,它只是在文档中使用的版本(无论是第一个还是最后一个或两者之间)。因此,例如,如果您有一个用于Linux的version块和一个用于Windows的块,则只有与您编译的系统匹配的块将最终出现在文档中。

模板之外的

static if块似乎以相同的方式运行。如果它们被编译进去,那么它们的ddoc注释最终会出现在文档中,而如果它们没有被编译,那么它们就没有。

但是,static if阻止模板内的似乎总是从第一个静态if块中获取文档,即使它总是false。但是考虑到那些静态ifs最终可能同时是truefalse(来自模板的不同实例),并且编译器实际上并不要求模板被实例化以使其ddoc注释结束在生成的文档中,这是有道理的。它没有像模板之外的static 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块中具有相同的功能。 e.g。

/// 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),您将不得不与正常版本分开生成文档。