我希望能够自省一个c++类的名称,内容(即成员及其类型)等。这里我说的是原生c++,而不是托管c++,托管c++有反射。我意识到c++使用RTTI提供了一些有限的信息。哪些附加库(或其他技术)可以提供这些信息?


当前回答

我想你可能会对Dominic Filion写的“在c++中使用反射模板”这篇文章感兴趣。它在Game Programming Gems 5的1.4部分。不幸的是,我没有带我的副本,但你可以找找看,因为我认为它解释了你想要的东西。

其他回答

你可以通过Boost::Hana库中的BOOST_HANA_DEFINE_STRUCT实现很酷的静态反射功能。 Hana非常通用,不仅适用于您所想到的用例,还适用于许多模板元编程。

我想宣传一下自动自省/反射工具包“IDK”的存在。它使用类似Qt的元编译器,并将元信息直接添加到目标文件中。据说它很容易使用。没有外部依赖。它甚至允许您自动反映std::string,然后在脚本中使用它。请看IDK

周围有两种反射。

Inspection by iterating over members of a type, enumerating its methods and so on. This is not possible with C++. Inspection by checking whether a class-type (class, struct, union) has a method or nested type, is derived from another particular type. This kind of thing is possible with C++ using template-tricks. Use boost::type_traits for many things (like checking whether a type is integral). For checking for the existence of a member function, use Templated check for the existence of a class member function? . For checking whether a certain nested type exists, use plain SFINAE .

如果你想要实现1),比如查看一个类有多少个方法,或者获取一个类id的字符串表示形式,那么恐怕标准c++没有办法做到这一点。你必须使用其中任何一个

一个元编译器,如Qt元对象编译器,它翻译你的代码,添加额外的元信息。 由宏组成的框架,允许您添加所需的元信息。你需要告诉框架所有的方法、类名、基类和它需要的一切。

c++的设计考虑到了速度。如果您想要高级别的检查,就像c#或Java所做的那样,不做一些额外的工作就无法做到这一点。

这些信息确实存在——但不是你需要的格式,而且只有当你导出你的类时。这适用于Windows,我不知道其他平台。使用存储类说明符,例如:

class __declspec(export) MyClass
{
public:
    void Foo(float x);
}

这使得编译器将类定义数据构建到DLL/Exe中。但它不是一种可以用于反射的格式。

在我的公司,我们建立了一个解释元数据的库,允许你在不插入额外的宏等到类本身的情况下反映一个类。它允许如下方式调用函数:

MyClass *instance_ptr=new MyClass;
GetClass("MyClass")->GetFunction("Foo")->Invoke(instance_ptr,1.331);

这有效地做到:

instance_ptr->Foo(1.331);

Invoke(this_pointer,…)函数有可变参数。显然,通过这样调用函数,你可以绕过诸如const-safety之类的东西,所以这些方面是作为运行时检查实现的。

我相信语法可以改进,到目前为止它只适用于Win32和Win64。我们发现它非常有用,可以为类提供自动GUI接口,在c++中创建属性,流到XML和从XML输出等等,而且不需要从特定的基类派生。如果有足够的需求,也许我们可以把它做成样子发布。

我想你可能会对Dominic Filion写的“在c++中使用反射模板”这篇文章感兴趣。它在Game Programming Gems 5的1.4部分。不幸的是,我没有带我的副本,但你可以找找看,因为我认为它解释了你想要的东西。