Std sonucu::type_info::Unmangling adı
Şu anda - diğer şeyler arasında - arama işlevi ile ilgili bilgileri yazdırmak için gereken bazı günlük kod üzerinde çalışıyorum. Bu nispeten kolay olmalı, standart C type_info
bir sınıf vardır. Bu typeid adı/fonksiyon/sınıf vs ... içerir. ama ezilmiş. Çok yararlı değil. I. e. typeid(std::vector<int>).name()
St6vectorIiSaIiEE
döndürür.
Bir şekilde bu yararlı bir şey üretmek için var mı? İçin std::vector<int>
gibi örnek yukarıda. Eğer sadece sigara-şablon sınıfları için çalışırsa, o zaman da iyi.
Çözüm gcc için çalışması gerekir, ama eğer port olsaydım daha iyi olurdu. Döndü olamaz o kadar önemli değil yani günlüğü için, ama hata ayıklama için yararlı olmalıdır.
CEVAP
Dikkat Bu soruya verilen cevap alır ve GManNickG, değerli geri bildirim kodu biraz temizlemiş. İki versiyonu gibidir: C 11 özellikleri ve C 98 sadece özellikleri ile başka bir ile bir.
Dosya içindeyazın.hes
#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
Dosya içindetype.cpp(C 11) gerektirir
#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
Kullanımı:
#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;
}
Yazdırır:
Ptr_base türü: Base*
Pointee türü: Derived
Linux 64 bit ve g 4.7.2 (Mingw32 win 32 XP SP2) g 4.7.2, g 4.9.0 20140302 (deneysel) tin 3.4 (trunk 184647), çınlama 3.5 (trunk 202594) ile test edilmiştir.
Olamaz C 11 özellikleri kullanırsanız, burada C 98, dosya yapılabilirtype.cppşimdi:
#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
(8, 2013 Eylül) güncelleyin
15 ** çağrı başarılı olduğunda The accepted answer (as of Sep 7, 2013),,bir işaretçi bir yerel için ayrılan dizi yığın döndürür... ah!
Ayrıca eğer bir tampon sağlamak, abi::__cxa_demangle()
öbek üzerinde tahsis edilecek varsayar unutmayın. On tampon yığın ayrılırken bir hata (gnu doktor):"Eğer output_buffer
yeterince uzun değilse, realloc
.*"Yığın işaretçisi realloc()
arama... ah! (Ayrıca bakınız Igor Skochinsky'In yorum.)
Kolayca doğrulamak hem de bu hatalar: sadece azaltmak arabellek boyutu kabul cevabı (7 Eylül 2013) 1024 için daha küçük bir şey, örneğin 16, ve verecek bir şey olan bir isimdeğil15 (20**. daha uzun ^em>değildenir). Hala, sistemi ve derleyici en iyi duruma getirmeleri bağlı olarak, bir çıkış olacak: çöp / hiçbir şey / program çökebilir.
İkinci hata doğrulamak için: 1 arabellek boyutu ayarlamak için ve uzun 1 karakter daha olan bir şey ile arayın. Çalıştırdığınızda, program neredeyse kesinlikle yığın işaretçisi ile realloc()
Ara dener gibi çöküyor.
(Dec eski cevap 27, 2010)
KeithB's code önemli değişiklikler:tampon ya da malloc ile ayrılmış veya BOŞ olarak belirtilmesi gerekir.Yığında ayırabilir.
Bilge bu durumu kontrol etmek için.
HAVE_CXA_DEMANGLE
bulmak için başarısız oldum. Bu kodu derlemek bile garanti değil, ancak __GNUG__
kontrol ederim. Kimsenin daha iyi bir fikri olan?
#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;
}
Yöntemde bir değişiklik dönen yüzer yü...
Seri Sorgu Sözlüğe Sonucu dönüştürmek...
En hızlı tamsayı bölme sıfıra bölme so...
Sütun kullanarak MySQL sorgu tümcesi b...
'C = sonucu s ve C ?...