C++ 如何使用Doxygen记录宏生成的类?

C++ 如何使用Doxygen记录宏生成的类?,c++,macros,doxygen,C++,Macros,Doxygen,我使用宏以以下方式生成类: 发电机h: class CLASS_NAME : public parent { //generate variables with names given by CLASS_VARIABLES using complicated //Boost.Preprocessor stuff. }; #undef CLASS_NAME #undef CLASS_VARIABLES #define DEFCLASS class CLASS_NAME : pu

我使用宏以以下方式生成类:

发电机h:

class CLASS_NAME : public parent
{
    //generate variables with names given by CLASS_VARIABLES using complicated
    //Boost.Preprocessor stuff.
};

#undef CLASS_NAME
#undef CLASS_VARIABLES
#define DEFCLASS class CLASS_NAME : public parent \
{ \
   ... whatever ... \
};
myclass.h:

#define CLASS_NAME MyClass
#define CLASS_VARIABLES (a, b, c, x, y, z)
#include "generator.h"
#define CLASS_NAME MyClass
#define CLASS_VARIABLES (a, b, c, x, y, z)
#include "generator.h"
DEFCLASS
实际的类更复杂,并且使用各种Boost.Preprocessor宏。有没有一种方法可以通过向generator.h添加注释来自动用Doxygen记录生成的类,或者生成一个带有文档的示例类?我尝试过启用启用预处理和宏扩展,但这似乎不够。

中的“其他地方的文档”如何


这行不通。Doxygen预处理器并不真正执行完整的文件包含(它只在包含的文件中查找宏定义;否则,ENABLE_PREPROCESSING指令将完全无用!)。因此,
#include“generator.h”
无效

如果用包含文件的内容实际替换
#include
指令,它将起作用。(我知道不是很有用)

另一种方法是修改文件,如下所示:

发电机h:

class CLASS_NAME : public parent
{
    //generate variables with names given by CLASS_VARIABLES using complicated
    //Boost.Preprocessor stuff.
};

#undef CLASS_NAME
#undef CLASS_VARIABLES
#define DEFCLASS class CLASS_NAME : public parent \
{ \
   ... whatever ... \
};
myclass.h:

#define CLASS_NAME MyClass
#define CLASS_VARIABLES (a, b, c, x, y, z)
#include "generator.h"
#define CLASS_NAME MyClass
#define CLASS_VARIABLES (a, b, c, x, y, z)
#include "generator.h"
DEFCLASS

但是如果您在每个源文件中多次使用DEFCLASS(可能是Doxygen的错误/缺陷),那么这将不起作用。

我建议将生成的类放在单独的头中,只记录头。在最好的情况下,生成的类更像是一个实现细节

另一个选择是编写脚本。无论是使用您最喜欢的脚本语言,还是类似的语言,都不会太糟糕

我猜你的生成器看起来很简单,可以生成锅炉板或特征之类的东西

GENERATE_CLASS(Foo);
GENERATE_CLASS(Bar);

像这样的东西是相当合理的grep素材。

在我写这篇文章的时候,doxygen将执行完整的文件包含,只要满足几个条件。从:

…预处理器进行解析,但在解析时实际上不包含代码 遇到一个#include(内部发现的#include除外){ …}块)

我通过实验发现的另一个未记录但直观的先决条件是,无论{…}块#include本身是什么,都必须记录下来。例如,在以下测试文件上运行doxygen将为结构
FOO::A
FOO::B
FOO::C
生成条目,前提是在配置文件中启用了
MACRO_EXPANSION
,所需的提取模式设置为“所有实体”,并且在
INCLUDE_PATH
中正确设置了boost文件夹:

#include <boost/preprocessor/iteration/local.hpp>
#include <boost/preprocessor/tuple/elem.hpp>

#define STRUCTS (A, B, C)

namespace FOO {
    #define BOOST_PP_LOCAL_MACRO(n) struct BOOST_PP_TUPLE_ELEM(3,n, STRUCTS) {};
    #define BOOST_PP_LOCAL_LIMITS (0,2)
    #include BOOST_PP_LOCAL_ITERATE()
}
#包括
#包括
#定义结构(A、B、C)
名称空间FOO{
#定义BOOST_PP_LOCAL_MACRO(n)struct BOOST_PP_TUPLE_ELEM(3,n,STRUCTS){};
#定义增压PP本地限制(0,2)
#包括BOOST_PP_LOCAL_ITERATE()
}

但是,删除
FOO
以将结构放置在匿名命名空间中将不会导致任何文档。因此,如果你能容忍在显式名称空间中包含“generator.h”,它会起作用。

Hmm,这不知怎么地不起作用。我不能完全像你建议的那样做,因为我实际的类名是类名和字符串的串联。我尝试使用
\class MyClass
,但似乎没有生成任何文档。是不是因为Doxygen搜索MyClass但没有找到它?我还尝试了
\class class\u nameConnegatedString
,但再次强调:没有。可能只是为该类添加一个转发声明。我想我不能使用您的修改,因为我再次在类定义中使用
\include
\define
s。我可以把
#define
s放在全班同学面前,但我不认为我可以去掉
#include
s…正如spyderfreek下面所说的,如果#include在{}块中,那么include将起作用。我不确定我是否正确理解了你的第一段。您是否建议创建一个包含预处理器输出的示例头?只有自动创建此标题,这才是一个好的解决方案。由于我使用cmake,这可能是可能的。然后我可以使用sweetrommie的建议在generator.h中创建注释。在第一段中,我不是指生成的输出。我的意思是将代码分离到它自己的头中。然后给出一般用途的执行摘要,而不是类的细节。另一种选择是创建一个纯虚拟接口,所有生成的类都从该接口“继承”(无论是字面上的继承还是模仿),并记录该接口。如果你想生成一些东西,我会使用cheetah。我不确定你关于记录#include指令所在块的第二个先决条件。我认为这是不必要的。