• <bdo id='KTzxE'></bdo><ul id='KTzxE'></ul>

    <small id='KTzxE'></small><noframes id='KTzxE'>

        <legend id='KTzxE'><style id='KTzxE'><dir id='KTzxE'><q id='KTzxE'></q></dir></style></legend>
        <tfoot id='KTzxE'></tfoot>

      1. <i id='KTzxE'><tr id='KTzxE'><dt id='KTzxE'><q id='KTzxE'><span id='KTzxE'><b id='KTzxE'><form id='KTzxE'><ins id='KTzxE'></ins><ul id='KTzxE'></ul><sub id='KTzxE'></sub></form><legend id='KTzxE'></legend><bdo id='KTzxE'><pre id='KTzxE'><center id='KTzxE'></center></pre></bdo></b><th id='KTzxE'></th></span></q></dt></tr></i><div id='KTzxE'><tfoot id='KTzxE'></tfoot><dl id='KTzxE'><fieldset id='KTzxE'></fieldset></dl></div>

        解开 std::type_info::name 的结果

        时间:2023-09-19

        <legend id='Gu1XZ'><style id='Gu1XZ'><dir id='Gu1XZ'><q id='Gu1XZ'></q></dir></style></legend>

        <small id='Gu1XZ'></small><noframes id='Gu1XZ'>

          • <bdo id='Gu1XZ'></bdo><ul id='Gu1XZ'></ul>
                <tfoot id='Gu1XZ'></tfoot>
                  <tbody id='Gu1XZ'></tbody>
                <i id='Gu1XZ'><tr id='Gu1XZ'><dt id='Gu1XZ'><q id='Gu1XZ'><span id='Gu1XZ'><b id='Gu1XZ'><form id='Gu1XZ'><ins id='Gu1XZ'></ins><ul id='Gu1XZ'></ul><sub id='Gu1XZ'></sub></form><legend id='Gu1XZ'></legend><bdo id='Gu1XZ'><pre id='Gu1XZ'><center id='Gu1XZ'></center></pre></bdo></b><th id='Gu1XZ'></th></span></q></dt></tr></i><div id='Gu1XZ'><tfoot id='Gu1XZ'></tfoot><dl id='Gu1XZ'><fieldset id='Gu1XZ'></fieldset></dl></div>

                  本文介绍了解开 std::type_info::name 的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  我目前正在处理一些日志代码,这些代码应该——除其他外——打印有关调用函数的信息.这应该相对容易,标准 C++ 有一个 type_info 类.这包含 typeid 的类/函数/等的名称.但它被破坏了.它不是很有用.IE.typeid(std::vector).name() 返回 St6vectorIiSaIiEE.

                  有没有办法从中产生一些有用的东西?就像上面例子的 std::vector 一样.如果它只适用于非模板类,那也没关系.

                  该解决方案应该适用于 gcc,但如果我可以移植它会更好.它是用于日志记录的,所以它不是那么重要以至于不能关闭,但它应该有助于调试.

                  解决方案

                  鉴于此问题/答案收到的关注,以及来自 GManNickG,我已经稍微清理了代码.给出了两个版本:一个有 C++11 特性,另一个只有 C++98 特性.

                  在文件type.hpp

                  #ifndef TYPE_HPP#define TYPE_HPP#include <字符串>#include <类型信息>std::string demangle(const char* name);模板std::string 类型(常量 T& t){返回 demangle(typeid(t).name());}#万一

                  在文件type.cpp(需要C++11)

                  #include "type.hpp"#ifdef __GNUG__#include #include <内存>#include std::string demangle(const char* name) {int 状态 = -4;//一些任意值以消除编译器警告//通过将标志 -std=c++11 传递给 g++ 来启用 c++11std::unique_ptr资源{abi::__cxa_demangle(name, NULL, NULL, &status),标准::免费};返回(状态== 0)?res.get() : 名称;}#别的//如果不是 g++,什么都不做std::string demangle(const char* name) {返回名称;}#万一

                  用法:

                  #include #include "type.hpp"struct Base { virtual ~Base() {} };结构派生:公共基础{};int main() {Base* ptr_base = new Derived();//请在您的代码中使用智能指针!std::cout <<"ptr_base 的类型:" <<类型(ptr_base)<

                  它打印:

                  ptr_base 的类型:Base*
                  指针类型:Derived

                  在 Linux 64 位和 g++ 4.7.2 (Mingw <2 XP32, Win32) 上使用 g++ 4.7.2, g++ 4.9.0 20140302 (experimental), clang++ 3.4 (trunk 184647), clang 3.5 (trunk 202594) 进行测试./p>

                  如果你不能使用 C++11 的特性,这里是如何在 C++98 中完成的,文件 type.cpp 现在是:

                  #include "type.hpp"#ifdef __GNUG__#include #include <内存>#include 结构句柄{字符* p;句柄(字符* ptr):p(ptr){}~handle() { std::free(p);}};std::string demangle(const char* name) {int 状态 = -4;//一些任意值以消除编译器警告处理结果(abi::__cxa_demangle(name, NULL, NULL, &status));返回(状态== 0)?结果.p:名称;}#别的//如果不是 g++,什么都不做std::string demangle(const char* name) {返回名称;}#万一

                  <小时><小时>

                  (2013 年 9 月 8 日更新)

                  接受的答案(截至 2013 年 9 月 7 日),当调用 abi::__cxa_demangle 时() 成功,返回一个指向本地、堆栈分配数组的指针...哎哟!
                  另请注意,如果您提供缓冲区,abi::__cxa_demangle() 假定它在堆上分配.在堆栈上分配缓冲区是一个错误(来自 gnu 文档):如果 output_buffer 不够长,则使用 realloc 进行扩展." 在指向堆栈的指针上调用realloc()...哎哟!(另请参阅 Igor Skochinsky 的友好评论.)

                  您可以轻松地验证这两个错误:只需将已接受答案(截至 2013 年 9 月 7 日)中的缓冲区大小从 1024 减小到更小的值,例如 16,并为其指定一个名称​​not 比 15 长(所以 realloc() 没有被调用).尽管如此,根据您的系统和编译器优化,输出将是:垃圾/无/程序崩溃.
                  验证第二个错误:将缓冲区大小设置为 1 并使用名称长度超过 1 个字符的名称来调用它.当您运行它时,程序几乎肯定会崩溃,因为它尝试使用指向堆栈的指针调用 realloc().

                  <小时>

                  (2010 年 12 月 27 日的旧答案)

                  对KeithB 的代码进行的重要更改:缓冲区必须由 malloc 分配或指定为 NULL. 不要在堆栈上分配它.

                  检查该状态也是明智之举.

                  我找不到HAVE_CXA_DEMANGLE.我检查了 __GNUG__ 虽然这并不能保证代码甚至可以编译.有人有更好的主意吗?

                  #include const string demangle(const char* name) {int 状态 = -4;char* res = abi::__cxa_demangle(name, NULL, NULL, &status);const char* const demangled_name = (status==0)?res:name;字符串 ret_val(demangled_name);免费(资源);返回 ret_val;}

                  I'm currently working on some logging code that supposed to - among other things - print information about the calling function. This should be relatively easy, standard C++ has a type_info class. This contains the name of the typeid'd class/function/etc. but it's mangled. It's not very useful. I.e. typeid(std::vector<int>).name() returns St6vectorIiSaIiEE.

                  Is there a way to produce something useful from this? Like std::vector<int> for the above example. If it only works for non-template classes, that's fine too.

                  The solution should work for gcc, but it would be better if I could port it. It's for logging so it's not so important that it can't be turned off, but it should be helpful for debugging.

                  解决方案

                  Given the attention this question / answer receives, and the valuable feedback from GManNickG, I have cleaned up the code a little bit. Two versions are given: one with C++11 features and another one with only C++98 features.

                  In file type.hpp

                  #ifndef TYPE_HPP
                  #define TYPE_HPP
                  
                  #include <string>
                  #include <typeinfo>
                  
                  std::string demangle(const char* name);
                  
                  template <class T>
                  std::string type(const T& t) {
                  
                      return demangle(typeid(t).name());
                  }
                  
                  #endif
                  

                  In file type.cpp (requires C++11)

                  #include "type.hpp"
                  #ifdef __GNUG__
                  #include <cstdlib>
                  #include <memory>
                  #include <cxxabi.h>
                  
                  std::string demangle(const char* name) {
                  
                      int status = -4; // some arbitrary value to eliminate the compiler warning
                  
                      // enable c++11 by passing the flag -std=c++11 to g++
                      std::unique_ptr<char, void(*)(void*)> res {
                          abi::__cxa_demangle(name, NULL, NULL, &status),
                          std::free
                      };
                  
                      return (status==0) ? res.get() : name ;
                  }
                  
                  #else
                  
                  // does nothing if not g++
                  std::string demangle(const char* name) {
                      return name;
                  }
                  
                  #endif
                  

                  Usage:

                  #include <iostream>
                  #include "type.hpp"
                  
                  struct Base { virtual ~Base() {} };
                  
                  struct Derived : public Base { };
                  
                  int main() {
                  
                      Base* ptr_base = new Derived(); // Please use smart pointers in YOUR code!
                  
                      std::cout << "Type of ptr_base: " << type(ptr_base) << std::endl;
                  
                      std::cout << "Type of pointee: " << type(*ptr_base) << std::endl;
                  
                      delete ptr_base;
                  }
                  

                  It prints:

                  Type of ptr_base: Base*
                  Type of pointee: Derived

                  Tested with g++ 4.7.2, g++ 4.9.0 20140302 (experimental), clang++ 3.4 (trunk 184647), clang 3.5 (trunk 202594) on Linux 64 bit and g++ 4.7.2 (Mingw32, Win32 XP SP2).

                  If you cannot use C++11 features, here is how it can be done in C++98, the file type.cpp is now:

                  #include "type.hpp"
                  #ifdef __GNUG__
                  #include <cstdlib>
                  #include <memory>
                  #include <cxxabi.h>
                  
                  struct handle {
                      char* p;
                      handle(char* ptr) : p(ptr) { }
                      ~handle() { std::free(p); }
                  };
                  
                  std::string demangle(const char* name) {
                  
                      int status = -4; // some arbitrary value to eliminate the compiler warning
                  
                      handle result( abi::__cxa_demangle(name, NULL, NULL, &status) );
                  
                      return (status==0) ? result.p : name ;
                  }
                  
                  #else
                  
                  // does nothing if not g++
                  std::string demangle(const char* name) {
                      return name;
                  }
                  
                  #endif
                  



                  (Update from Sep 8, 2013)

                  The accepted answer (as of Sep 7, 2013), when the call to abi::__cxa_demangle() is successful, returns a pointer to a local, stack allocated array... ouch!
                  Also note that if you provide a buffer, abi::__cxa_demangle() assumes it to be allocated on the heap. Allocating the buffer on the stack is a bug (from the gnu doc): "If output_buffer is not long enough, it is expanded using realloc." Calling realloc() on a pointer to the stack... ouch! (See also Igor Skochinsky's kind comment.)

                  You can easily verify both of these bugs: just reduce the buffer size in the accepted answer (as of Sep 7, 2013) from 1024 to something smaller, for example 16, and give it something with a name not longer than 15 (so realloc() is not called). Still, depending on your system and the compiler optimizations, the output will be: garbage / nothing / program crash.
                  To verify the second bug: set the buffer size to 1 and call it with something whose name is longer than 1 character. When you run it, the program almost assuredly crashes as it attempts to call realloc() with a pointer to the stack.


                  (The old answer from Dec 27, 2010)

                  Important changes made to KeithB's code: the buffer has to be either allocated by malloc or specified as NULL. Do NOT allocate it on the stack.

                  It's wise to check that status as well.

                  I failed to find HAVE_CXA_DEMANGLE. I check __GNUG__ although that does not guarantee that the code will even compile. Anyone has a better idea?

                  #include <cxxabi.h>
                  
                  const string demangle(const char* name) {
                  
                      int status = -4;
                  
                      char* res = abi::__cxa_demangle(name, NULL, NULL, &status);
                  
                      const char* const demangled_name = (status==0)?res:name;
                  
                      string ret_val(demangled_name);
                  
                      free(res);
                  
                      return ret_val;
                  }
                  

                  这篇关于解开 std::type_info::name 的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                    <legend id='C75Bi'><style id='C75Bi'><dir id='C75Bi'><q id='C75Bi'></q></dir></style></legend>
                    <i id='C75Bi'><tr id='C75Bi'><dt id='C75Bi'><q id='C75Bi'><span id='C75Bi'><b id='C75Bi'><form id='C75Bi'><ins id='C75Bi'></ins><ul id='C75Bi'></ul><sub id='C75Bi'></sub></form><legend id='C75Bi'></legend><bdo id='C75Bi'><pre id='C75Bi'><center id='C75Bi'></center></pre></bdo></b><th id='C75Bi'></th></span></q></dt></tr></i><div id='C75Bi'><tfoot id='C75Bi'></tfoot><dl id='C75Bi'><fieldset id='C75Bi'></fieldset></dl></div>

                  • <tfoot id='C75Bi'></tfoot>

                        <tbody id='C75Bi'></tbody>
                      • <bdo id='C75Bi'></bdo><ul id='C75Bi'></ul>

                        1. <small id='C75Bi'></small><noframes id='C75Bi'>