没有宏的c++简单反射:打印变量名及其值

C++ Simple Reflection without Macros: Print Variable Name and Its Value

本文关键字:变量名 打印 反射 c++ 简单      更新时间:2023-10-16

在c++中是否有一种非宏的方式来打印变量名和它的值?以下是宏方式:

#define SHOW(a) std::cout << #a << ": " << (a) << std::endl

PS:我正在使用Linux,不需要跨平台的解决方案

不,c++不支持反射,唯一的方法(据我所知)是使用宏。

您可以使用动态符号,但它只能在使用-rdynamic标志编译的共享库或可执行文件中工作。它将只识别默认动态可见性的全局变量。

#include <dlfcn.h>
#include <iostream>
int NameMe = 42;
const char *GetName(const void *ptr)
{
    Dl_info info;
    if (dladdr(ptr, &info))
        return info.dli_sname;
    else
        return NULL;
}
    template<typename T>
void Dump(const T &t)
{
    const char *name = GetName(&t);
    if (name)
        std::cout << name;
    else
        std::cout << "<unknown>";
    std::cout << ": " << t << std::endl;
}
int main()
{
    int NoName = 33;
    Dump(NameMe);
    Dump(NoName);
    return 0;
}
$ g++ dump.cpp -ldl -rdynamic
$ ./a.out
NameMe: 42
<unknown>: 33

不行

如果没有宏,你必须这样做:
std::cout <<"a : " << a << std::endl; 

别无他法

如果您可以让所有的类都从一个共同的祖先派生,那么您可以提供一个虚函数来实现这一点。我还没有尝试过这个模板,它可能不工作-一些反馈将不胜感激。

struct Reflector
{
    virtual void Show() = 0;
};
template<class a, char name[]>
struct ReflectorImpl : public Reflector
{
    virtual void Show()
    {
        std::cout << name << ": " << *this << std::endl;
    }
};
class MyClass: public ReflectorImpl<MyClass, "MyClass">
{
};

是;在c++ 17中,您可以使用PFR(在c++ 17模式下)来获得非宏反射的重要级别。有一些相关的机制可以反映"string-value";

  1. 见https://github.com/apolukhin/magic_get;
  2. 和https://github.com/Neargye/magic_enum .