2016-04-10 12 views
15

Dopo la compilazione con g++-4.9.3 -std=c++11 il codiceCome rimuovere i nomi storti dei lambda in C++?

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

uscite Z4mainEUlvE_ come il nome storpiato del lambda data su Linux x86_64. Tuttavia, lo strumento c++filt non è in grado di sbloccarlo. Emette solo l'input che gli viene dato, Z4mainEUlvE_.

Come posso sbloccarlo?

+0

Cosa ti aspetti che l'output sia? '[]()'? – nwp

+2

lambda: un oggetto funzione senza nome in grado di catturare variabili nell'ambito. Cosa vorresti che il nome fosse? –

+1

@richard E due lambda, conosciuti come 'bob', naturalmente. – Yakk

risposta

15

È possibile utilizzare speciali abi::__cxa_demangle la funzione di GCC:

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

uscita:

main::{lambda()#1} 

Secondo The Documentation questa funzione restituisce un c-style stringa con terminazione zero assegnata utilizzando std::malloc che il chiamante deve liberare utilizzando std::free. Questo esempio utilizza un puntatore intelligente per liberare automaticamente la stringa restituita alla fine dell'ambito.

7

Utilizzando c++filt versione 070207 20070207:

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

Anche se, come i commentatori hanno suggerito, questi nomi non sono sempre del tutto utile.

+0

In alternativa puoi semplicemente reindirizzare l'output del programma a 'C++ filt', come' ./a.out | C++ filt' – vsoftco

1

Si potrebbe provare a utilizzare boost::core::demangle ma non so se i risultati saranno diversi.

Per esempio

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

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