【发布时间】:2013-08-09 20:57:50
【问题描述】:
C++(非常多)不幸的设计缺陷之一是,在使用模板元编程时,基本上不可能将实现与接口分开。
我的图书馆里到处都是这样的东西:
template <typename Ma, typename Mb>
typename boost::enable_if_c<
detail::IsMatrix<Ma>::val and detail::IsMatrix<Mb>::val and
detail::MatrixDimensionCheck<Ma,Mb>::isStaticMatch,
bool>::type
operator==(const Ma &a, const Mb &b) {
return detail::matrixEqual(a,b);
}
如果这不可读,我不怪你。如果参数是矩阵和匹配维度,则大部分混乱只是将返回类型定义为bool,如果它们是其他东西,则定义为未定义(因此依靠 SFINAE 来防止此运算符隐藏其他重要的东西)。
由于本质上是静态类型检查函数的内容现在嵌入到我的普通 C++ 函数的签名中,这些实现内容将出现在生成的文档中。
我不希望用户必须阅读此内容。他们只需要知道这个函数返回一个bool(这几乎不可能通过阅读上面的内容来判断)。在文档中,我可以用简单的英语简洁地解释,这个运算符只接受矩阵。
有没有办法说服 Doxygen 将这种类型的混乱渲染为bool? (我假设或多或少没有办法直接在代码中清理它,但如果你能想到一些想法,欢迎提出想法)。
【问题讨论】:
-
我更喜欢手写文档而不是“自动生成”文档是有原因的。我几乎总是花更多的时间来设置文档系统/将其修复到可接受的范围内,同时我本可以已经以实际好的格式编写所有文档。
-
@nightcracker:当然,直到您更改任何内容,例如参数、函数等,而无需更新文档。然后它变得不同步并且变得比无用更糟糕。此外,Doxygen 也很好地支持手写文档。
-
可能相关的是this问题。
-
Bjarne Stroupstrup 在他的 FAQ 中有一条评论:“像所有强大的技术一样,它们 [模板元编程] 很容易被过度使用” 别误会,我喜欢模板元编程。但它必须与常识一起使用。它只是一个建议,而不是对您的代码的批评。
-
我会使用一个库的(非常麻烦,我同意)方法,它的实现严重依赖于这种不可隐藏的模板魔法,就是制作一个单独的头文件,其中只包含干净的 " 为if" 版本的接口并在该接口上运行 doxygen。当然,对于大型库,这可能会变得非常麻烦,但我已经为小型单文件仅标头库完成了此操作,并且效果很好。当然,您必须使两个文件保持同步,但是当无法直接从源文件生成文档时,情况总是如此。