2016-04-10 20 views
15

Nach dem Übersetzen mit g++-4.9.3 -std=c++11 der CodeWie man entstellte Namen von C++ - Lambdas entmangelt?

#include <iostream> 
#include <typeinfo> 
using namespace std; 
int main() { cout << typeid([]{}).name() << endl; } 

Ausgänge Z4mainEUlvE_ als verstümmelten Namen des auf Linux Lambda gegeben x86_64. Das Tool c++filt kann es jedoch nicht entfernen. Es gibt nur die Eingabe aus, Z4mainEUlvE_.

Wie entwirre ich es?

+0

Was erwarten Sie von der Ausgabe? '[]()'? – nwp

+2

Lambda: ein unbenanntes Funktionsobjekt, das Variablen im Gültigkeitsbereich erfassen kann. Wie möchten Sie den Namen haben? –

+1

@richard Und zwei lambdas, bekannt als 'bob' natürlich. – Yakk

Antwort

15

Sie spezielle GCC abi::__cxa_demangle Funktion verwenden können:

#include <memory> 
#include <cstdlib> 
#include <cxxabi.h> 
#include <iostream> 

// delete malloc'd memory 
struct malloc_deleter 
{ 
    void operator()(void* p) const { std::free(p); } 
}; 

// custom smart pointer for c-style strings allocated with std::malloc 
using cstring_uptr = std::unique_ptr<char, malloc_deleter>; 

int main() 
{ 
    // special function to de-mangle names 
    int error; 
    cstring_uptr name(abi::__cxa_demangle(typeid([]{}).name(), 0, 0, &error)); 

    if(!error) 
     std::cout << name.get() << '\n'; 
    else if(error == -1) 
     std::cerr << "memory allocation failed" << '\n'; 
    else if(error == -2) 
     std::cerr << "not a valid mangled name" << '\n'; 
    else if(error == -3) 
     std::cerr << "bad argument" << '\n'; 
} 

Ausgang:

main::{lambda()#1} 

Nach The Documentation diese Funktion eine c-Stil gibt nullterminierte Zeichenfolge, die unter Verwendung von std::malloc zugewiesen wurde, die der Anrufer unter Verwendung von std::free freigeben muss. In diesem Beispiel wird ein Smartzeiger verwendet, um die zurückgegebene Zeichenfolge am Ende des Bereichs automatisch freizugeben.

7

Mit c++filt Version 070207 20070207:

$ c++filt -n Z4mainEUlvE_ 
main::'lambda'() 

Obwohl als die commen vorgeschlagen haben, sind diese Namen nicht immer ganz hilfreich.

+0

Alternativ können Sie auch die Ausgabe des Programms an 'C++ filt' übergeben, wie' ./a.out | C++ filt' – vsoftco

1

Sie könnten versuchen, boost::core::demangle zu verwenden, aber ich weiß nicht, ob Ihre Ergebnisse anders sein werden.

Zum Beispiel

#include <boost/core/demangle.hpp> 
#include <iostream> 

int main() { 
    std::cout << boost::core::demangle (typeid ([](){}).name()) << std::endl; 
}