【问题标题】:Is it possible to print the name of an object?是否可以打印对象的名称?
【发布时间】:2016-09-28 08:40:23
【问题描述】:

我已经知道在 C 或 C++ 中都无法打印变量的名称,这在其他 StackOverflow 帖子中有所提及。

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

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

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

【问题讨论】:

  • 对象名还是对象类型名?
  • 在 C/C++ 中不能打印变量的名称并不完全正确。实际上你可以使用预处理器来做到这一点:#define VAR_TO_STRING(VAR) #VAR
  • 对象名称,请。

标签: c++ oop stl objectname


【解决方案1】:

你可以使用:

typeid(someObject).name();

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

返回一个实现定义的以空字符结尾的字符串 包含类型的名称。不提供任何保证,在 特别是,返回的字符串对于几种类型可以是相同的,并且 在同一程序的调用之间进行更改。

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

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

【讨论】:

    【解决方案2】:

    这是我用的:

    #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
        }
    

    它通常给出一个对人类友好的 Type 版本。根据您的编译器(和版本),子字符串可能会有所不同。

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

    【讨论】:

    • 如果使用的编译器都不是这些怎么办?我会添加#else 并返回"THIS FUNCTION IS NOT SUPPORTED" 或其他内容。
    【解决方案3】:

    你可以使用

    #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阿迪

    输出格式是类名的长度,后跟其名称。

    【讨论】:

      【解决方案4】:

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

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

      您可以使用模板类的重载来获取类的名称,然后您只需为要获取名称的每种类型实现该类的部分特化。

      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 容器的此类类和特化可在此处获得: https://github.com/Gemini67/Celma

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-24
        • 2023-03-22
        • 2020-09-06
        • 2020-06-22
        • 2016-11-30
        相关资源
        最近更新 更多