【问题标题】:How to document C++ templates and template metafunctions with doxygen?如何使用 doxygen 记录 C++ 模板和模板元函数?
【发布时间】:2012-11-01 19:00:15
【问题描述】:

是否有关于如何使用 Doxygen 记录 C++ 模板和模板元函数的指南?

例如:

/// @brief metafunction for generation of a map of message types to
/// their associated callbacks.
/// @tparam Seq the list of message types
template< class Seq >
struct generate_callback_map
{
    typedef typename mpl::transform< Seq
                                   , build_type_signature_pair< mpl::_1 > 
                                   >::type vector_pair_type;
    typedef typename fusion::result_of::as_map< vector_pair_type >::type type;
};

到目前为止,我看到了以下建议:

  • @tparam 用于记录模板参数。
  • @arg 记录模板参数的另一种方式。
  • @brief 用于描述元功能。

应该如何记录元函数的“返回类型”?

对于将 Doxygen 与 C++ 模板一起使用,有人有什么好的建议或个人偏好吗?

【问题讨论】:

  • @Pubby:这是一个非常有用的建议。你会用什么,而不是?
  • @JanHudec 自己编写而不是生成它。当然,使用样式指南和一致的格式。可读代码对 TMP 来说是一个巨大的优势,因为它们是一个泄漏的抽象。使用伪代码进行解释会有所帮助,因为 C++ 语法很烂。
  • @Pubby 一定是在开玩笑。好的文档是你从不看代码的时候。您在标题中阅读解释 cmets,您甚至不关心查看实现,也就是说,您不关心代码样式、格式、可读性等等——这是一个很好的文档。 Doxygen 只是一个从源代码(最好是从标题中) 中提取这些文档的工具。当然,如果你想像一堆 «targzipped» 标题而不是 html/pdf/whatever 那样分发 API 描述,那么,祝你好运;我更喜欢使用 Doxygen

标签: c++ templates doxygen


【解决方案1】:

@tparam 用于模板参数,@arg 用于函数参数。对于返回值,@return。这里没有回报。只有typedefs。

顺便说一句,您的示例代码看起来不像元函数。元函数是毛茸茸的野兽,它利用 SFINAE 来做 C++ 原本不打算做的事情(例如反射)。您的 generate_callback_map 看起来就像模板 typedef 的 C++03 替身。

你缺少的是关于你的 typedef 的文档和关于如何使用这个模板的文档。

/// @brief metafunction for generation of a map of message types to
/// their associated callbacks.
/// @details
/// Usage: Use <tt>generate_callback_map<Type>::type</tt> to ...
/// @tparam Seq the list of message types
/// 
template< class Seq >
struct generate_callback_map
{
  /// @brief It's a good idea to document all of your typedefs.
  typedef typename mpl::transform< Seq
                                 , build_type_signature_pair< mpl::_1 > 
                                 >::type vector_pair_type;

  /// @brief This is why generate_callback_map exists. Document it!
  typedef typename fusion::result_of::as_map< vector_pair_type >::type type;
};

【讨论】:

  • 在 C++ 中,“元函数”通常指的是诸如 OP 之类的代码。是的,它是一个 typedef,但 typedef 包含的类型是评估指定的编译时“函数”的结果。
  • 我认为这里没有回报。正式的类没有返回值,但逻辑上type typedef 是一个返回值。并且会更好地记录在该类的主要文档主体中,而不是作为单独的成员。
  • 有人可能会说这里有一个返回,在同样的意义上这个结构定义是一个函数。但是从 Doxygen 和相关/兼容的文档生成器的角度来看,尝试用 @return 标记示例中的任何内容只会混淆它。 @david 的示例 typedef 文档提供此功能并且是明确的,但可以通过结构本身的简短文档来扩充。
  • 这个其实应该选为正确答案
  • Doxygen 文档中指向 tparam 的最新链接:doxygen.nl/manual/commands.html#cmdtparam
【解决方案2】:

我认为不可能将文档高级模板构造与 doxygen 一起使用,因为它最初是为面向对象的范例而不是元编程设计的。作为说明,GNU STL (libstdc++) 使用 doxygen,但在 STL 中记录元编程的 poor job

另一方面,boost 使用自己的工具:QuickBook 使用独立的文本文件和 doxygen 记录的源代码来生成 BoostBook 标记(DocBook 的扩展),然后生成 html/pdf。 result 比 libstdc++ 提供更多信息,但显然需要开发人员做更多的工作。

由于 boost 文档可以说是最适合元编程的文档之一,您可以走这条路,特别是因为它补充了 doxygen - 您可以重用现有的标记。

虽然它不能完全回答您的问题,但您可能对最近的 clang developments 感兴趣。当使用 --with-extra-options=-Wdocumentation 构建 clang 时,它会在语义上检查您的 doxygen 标记与您的代码并生成文档警告。强制您保持文档/代码同步。

【讨论】:

  • 我同意,大多数 boost 文档都非常好,遵循他们的方法当然很有意义。
  • 这里有很好的信息。 Clang/LLVM 文档检查的链接非常有用!我只需要使用-Wdocumentation 来让它工作。不过,并没有严格回答 OP 的问题。
  • Re “作为说明,GNU STL (libstdc++) 使用 doxygen,但在 STL 中记录元编程方面做得很差。” GNU 在文档方面做得很差。查看源代码。现有的少量评论充其量是很差的。用 GNU 糟糕的评论作为 doxygen 失败的例子是不公平的。一个更好的例子是一些评论很好的来源,但在 doxygen 中看起来很糟糕。
  • @DavidHammen 确实这个例子不是最好的,但我很难找到更好的例子:在 doxygen 中记录良好的库倾向于使用模板,而模板重的库倾向于使用除多氧。欢迎提出建议!
  • @Antoine - Eigen,一个。 Eigen 是大量模板化的。他们的 API 是由 doxygen 自动生成的。他们的 API 文档是否独立存在?当然不是。对于任何足够复杂的软件包,API 是不够的。想想 C++ 标准库。需要多本书来描述该图书馆。这里只是 Eigen 源代码的一个示例:Matrix.h, Eigen release 3.1
猜你喜欢
  • 2014-03-21
  • 2015-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-13
  • 1970-01-01
  • 2015-01-14
  • 1970-01-01
  • 2016-02-24
相关资源
最近更新 更多