C++ C++;元编程doxygen文档
我正在记录一些大量使用元编程的代码,例如:C++ C++;元编程doxygen文档,c++,templates,doxygen,C++,Templates,Doxygen,我正在记录一些大量使用元编程的代码,例如: template<rysq::type A, rysq::type B, rysq::type C, rysq::type D, class Transform> struct Kernel<meta::braket<A,B,C,D>, Transform, typename boost::enable_if< quadrature<met
template<rysq::type A, rysq::type B, rysq::type C, rysq::type D, class Transform>
struct Kernel<meta::braket<A,B,C,D>, Transform,
typename boost::enable_if<
quadrature<meta::braket<A,B,C,D>, Transform> >::type>
: Eri <Transform> {
模板
结构内核::类型>
:埃里{
使用doxygen记录此类构造的好方法是什么?元编程似乎实现了数学。我会在doxygen文档中用latex Escape来描述数学公式。使用预处理器宏。下面是一个来自(目前正在排队等待审查以纳入Boost)的示例: 使用
#define
d宏名称,而不是模板参数,在任何需要它们的地方,例如:
/*! \brief The integer_t class template.
This class implements the standard aribitrary-length %integer type.
[...lots more documentation omitted...]
*/
template<BOOST_XINT_INITIAL_APARAMS>
class integer_t: virtual public detail::integer_t_data<BOOST_XINT_APARAMS>,
public detail::nan_functions<detail::integer_t_data<BOOST_XINT_APARAMS>::
NothrowType::value, // ...lots more base classes omitted...
{
// ...etcetera
结果是Doxygen看到“…”或“其他”如果您在类本身的文档中描述了模板参数,那么库的用户只需要在他可能查找它们的地方看到它们;它们将隐藏在其他任何地方
作为此设计的另一个优势,如果您需要更改模板参数列表,只需在宏定义和实际使用更改参数的函数中更改它们。其他一切都将自动适应。以下是我的看法:
///
/// \defgroup Kernel Kernel
///
/// \brief Kernel does this and that
/// \{
/// \brief Kernel template class brief description.
template<Braket,Transform,Boolean>
struct Kernel
{};
/// \brief Kernel partial template specialization brief description.
///
/// More detailed description...<br>
/// Partially specializes Kernel with meta::braket<A,B,C,D\>.<br>
/// If quadrature<meta::braket<A,B,C,D\>, Transform\> is true then enable
/// this algorithm, otherwise enable this other algorithm.<br>
/// Inherits privately from template class Eri<Transform\><br>
/// \tparam A template parameter A of type rysq::type, documentation and concepts
/// \tparam B template parameter B of type rysq::type, documentation and concepts
/// \tparam C template parameter C of type rysq::type, documentation and concepts
/// \tparam D template parameter D of type rysq::type, documentation and concepts
/// \tparam Transform template parameter class Transform documentation and concepts
/// \see Kernel\<Braket,Transform,Boolean\>
/// \see Eri
/// \see meta::braket
/// \see quadrature
#ifdef DOXY
// This is the documentation version
template<A,B,C,D,Transform>
struct Kernel<Braket,Transform,Boolean>
#else
// This is what gets compiled
template<rysq::type A, rysq::type B, rysq::type C, rysq::type D, class Transform>
struct Kernel<meta::braket<A,B,C,D>, Transform,typename boost::enable_if<quadrature<meta::braket<A,B,C,D>, Transform> >::type>
#endif
: Eri <Transform> {};
/// \}
///
///\defgroup内核
///
///\brief内核做这做那
/// \{
///\brief内核模板类简要说明。
模板
结构内核
{};
///\brief内核部分模板专门化简要说明。
///
///更详细的描述…
///使用meta::braket部分地专门化内核。
///如果正交为真,则启用
///此算法,否则启用此其他算法。
///从模板类Eri私有继承
///\t打印rysq::类型、文档和概念的模板参数A
///\t RAM B模板参数B类型为rysq::类型、文档和概念
///\t RAM C模板参数C类型rysq::类型、文档和概念
///\t RAM D模板参数D类型为rysq::类型、文档和概念
///\t RAM转换模板参数类转换文档和概念
///\请参阅内核\
///\参见Eri
///\参见meta::braket
///\参见正交
#ifdef-DOXY
//这是文档版本
模板
结构内核
#否则
//这就是编译的内容
模板
结构内核
#恩迪夫
:Eri{};
/// \}
不要忘记在Doxygen的预处理器的预定义部分添加DOXY
我通常更喜欢对代码的用户隐藏实现细节,所以我会更改Doxygen看到的内容。
在本例中,您将在一个组(内核组)下找到所有专门化,在类列表下,所有专门化都将分组在一起,并且不会有一个很长且不可理解的名称
希望有帮助。我不喜欢带有附加宏/代码的解决方案,例如 下面是我的解决方案,它基于对Doxygen生成的HTML页面的后处理 这是一个在Linux下工作的python脚本。它禁止模板类和结构引用页中的所有“”以及它们的“所有成员页列表”中的“” 在每一个记录的方法之前,最小的、侵入性较小的“模板”仍然存在 以“html/”目录(生成文档的地方)作为参数运行脚本
#!/usr/bin/python
import subprocess
import sys
import re
def processFile( fileName):
f = open( fileName, 'r')
content = f.read();
f.close();
regex = re.compile( "(<.*>).*(Template Reference|Member List)")
match = re.search( regex, content)
if not match:
return
toRemove = match.group(1)
regex = re.compile(toRemove)
content = re.sub( regex, "", content)
f = open( fileName, 'w')
f.write( content)
f.close()
path = sys.argv[1]
finder = subprocess.Popen(["find", path, "-name", "class*.html", "-o", "-name", "struct*.html"], stdout = subprocess.PIPE)
(files, junk) = finder.communicate()
files = files.splitlines()
print files
for fname in files:
if fname == "":
continue
processFile(fname)
嗨,我可能不清楚,我需要文档化编程逻辑,而不是数学描述。“AAA我会说你需要同时文档。”AAA,当你把C++和元编程技术剥离时,在显示的片段中保留了什么编程逻辑?你是什么意思?我不在下面。quite@aaa我对tem不够精通板元编程,可以看到所显示的片段中的编程逻辑。没关系。我最好把它留给专家。这正是我为什么不在C++中进行模板元编程的原因。这太荒谬了。language@aaa这似乎极不可能,这取决于你所说的“更好”是什么意思当然。@aaa:你知道doxygen命令吗?我建议你编辑你的问题,以显示doxygen当前输出的内容,以及你希望它输出的内容。人们可以在任何doxygen设置上磨练,这可能会让你更接近你的目标。事实上,这个问题太模糊了。我讨厌添加额外的宏/代码just对于doxygen来说,似乎编写文档注释是不够的。希望它们能尽快支持模板。对于库代码来说,以一种良好的格式将所有文档放在用户指尖的便利性超过了我个人不得不添加宏和代码的不便。YMMV.:-)
///
/// \defgroup Kernel Kernel
///
/// \brief Kernel does this and that
/// \{
/// \brief Kernel template class brief description.
template<Braket,Transform,Boolean>
struct Kernel
{};
/// \brief Kernel partial template specialization brief description.
///
/// More detailed description...<br>
/// Partially specializes Kernel with meta::braket<A,B,C,D\>.<br>
/// If quadrature<meta::braket<A,B,C,D\>, Transform\> is true then enable
/// this algorithm, otherwise enable this other algorithm.<br>
/// Inherits privately from template class Eri<Transform\><br>
/// \tparam A template parameter A of type rysq::type, documentation and concepts
/// \tparam B template parameter B of type rysq::type, documentation and concepts
/// \tparam C template parameter C of type rysq::type, documentation and concepts
/// \tparam D template parameter D of type rysq::type, documentation and concepts
/// \tparam Transform template parameter class Transform documentation and concepts
/// \see Kernel\<Braket,Transform,Boolean\>
/// \see Eri
/// \see meta::braket
/// \see quadrature
#ifdef DOXY
// This is the documentation version
template<A,B,C,D,Transform>
struct Kernel<Braket,Transform,Boolean>
#else
// This is what gets compiled
template<rysq::type A, rysq::type B, rysq::type C, rysq::type D, class Transform>
struct Kernel<meta::braket<A,B,C,D>, Transform,typename boost::enable_if<quadrature<meta::braket<A,B,C,D>, Transform> >::type>
#endif
: Eri <Transform> {};
/// \}
#!/usr/bin/python
import subprocess
import sys
import re
def processFile( fileName):
f = open( fileName, 'r')
content = f.read();
f.close();
regex = re.compile( "(<.*>).*(Template Reference|Member List)")
match = re.search( regex, content)
if not match:
return
toRemove = match.group(1)
regex = re.compile(toRemove)
content = re.sub( regex, "", content)
f = open( fileName, 'w')
f.write( content)
f.close()
path = sys.argv[1]
finder = subprocess.Popen(["find", path, "-name", "class*.html", "-o", "-name", "struct*.html"], stdout = subprocess.PIPE)
(files, junk) = finder.communicate()
files = files.splitlines()
print files
for fname in files:
if fname == "":
continue
processFile(fname)