2016-04-10 1 views
15

После компиляции с g++-4.9.3 -std=c++11 КодексаКак развязать искаженные имена C++ lambdas?

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

выходы Z4mainEUlvE_ как искаженное имя данного лямбда на Linux x86_64. Однако инструмент c++filt не может его развернуть. Он просто выводит введенный ему вход, Z4mainEUlvE_.

Как мне его переманить?

+0

Что вы ожидаете от вывода? '[]()'? – nwp

+2

lambda: неназванный функциональный объект, способный захватывать переменные в области видимости. Что бы вы хотели, чтобы имя было? –

+1

@richard И две лямбды, известные как 'bob', конечно. – Yakk

ответ

15

Вы можете использовать специальный abi::__cxa_demangle функцию ССЗ:

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

Выход:

main::{lambda()#1} 

По The Documentation эта функция возвращает кесарево стиль с нулевым окончанием Строка, выделенная с использованием std::malloc, которой вызывающий абонент должен освободить, используя std::free. В этом примере используется умный указатель, чтобы автоматически освободить возвращаемую строку в конце области действия.

7

Использование c++filt версии 070207 20070207:

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

Хотя как комментаторы предположили, эти имена не всегда полностью полезно.

+0

В качестве альтернативы вы можете просто передать вывод программы в 'C++ filt', например' ./a.out | C++ filt' – vsoftco

1

Вы можете попробовать использовать boost::core::demangle, но я не знаю, будут ли ваши результаты другими.

Например

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

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

Если вам не нужно это внутри вашего кода, и его только для удовольствия, то используйте онлайн-инструмент, например http://d.fuqu.jp/c++filtjs/, который для Z4mainEUlvE_ возвращает main::{lambda()#1}.

Другие инструменты можно найти под this Stack Overflow question.