是否可以打印对象的名称?

Is it possible to print the name of an object?

我已经知道在 C 或 C++ 中无法打印变量的名称,其他 Whosebug 帖子中提到了这一点。

不过我知道在其他语言中,例如 Delphi,可以打印对象的类名。我不知道这在 C++ 中是否可行。

因此我的问题是:是否可以打印对象的对象名称?

一些背景:我正在编写一个程序,它使用 STL 向量来跟踪位置和值(都在单独的向量中),我想打印向量的内容,前面是对象名称(这样我就可以知道我是在查看位置还是在查看值)。

您可以使用:

typeid(someObject).name();

但是 return 值是实现定义的,根本不需要 return 任何有用或可读的东西。

Returns an implementation defined null-terminated character string containing the name of the type. No guarantees are given, in particular, the returned string can be identical for several types and change between invocations of the same program.

因此,如果您需要它的不仅仅是记录,那么我建议您自己跟踪它们。

有关 .name() 的更多信息。

您可以使用

#include <typeinfo>
typeid(object).name()

这是相同的工作代码 -

#include <iostream>
#include <typeinfo>
using namespace std;

class Adi {
int a;
int b;
};

int main() {
Adi obj, obj2;
cout << typeid(obj2).name() << endl;
return 0;
}

输出: 3阿迪

输出格式是 class-name 的长度后跟它的名字。

这是我用的:

#include <cstddef>
#include <cstring>
#include <iostream>
#include <ostream>

    template < class T >
    std::string type_name()
    {
#ifdef __clang__
        std::string p = __PRETTY_FUNCTION__;
        return p.substr( 43, p.length() - 43 - 1 );
#elif defined( __GNUC__ )
        std::string p = __PRETTY_FUNCTION__;
#if __cplusplus < 201402
        return p.substr( 57, p.length() - 53 - 62 );
#else
        return p.substr( 46, p.length() - 46 - 1 );
#endif
#elif defined( _MSC_VER )
        std::string p = __FUNCSIG__;
        return p.substr( 38, p.length() - 38 - 7 );
#else
        return std::string("This function is not supported!");
#endif
    }

它通常给出一个人性化的类型版本。根据您的编译器(和版本),子字符串可能不同。

Coliru 示例:http://coliru.stacked-crooked.com/a/bcdb77a7519136ea

可以使用预处理器打印变量名:

#define STRINGIFY(a)  #a
#define VAR_NAME(a)  STRINGIFY( a)

int  my_var = 42;
std::cout << "var name = " << VAR_NAME( my_var) << std::endl;

获取 class 的名称你可以使用模板 class 的重载,然后你只需要为你想要的每种类型实现这个 class 的部分特化获取名称。

template< typename T> class type
{
public:
   static constexpr const char* name() {
      return "unknown";
   } // end type< T>::name
}; // type< T>

template<> class type< int>
{
public:
   static constexpr const char* name() {
      return "int";
   }
}

template<> class type< std::string>
{
public:
   static constexpr const char* name() {
      return "std::string";
   }
}

std::cout << "type name = " << type< int>::name() << std::endl;

所有 POD 类型和 STL 容器的 classes 和专业化可在此处获得: https://github.com/Gemini67/Celma

还包含获取变量类型名称的解决方案。