如何解析C++ Lambda表达式的混淆名称?

18

使用 g++-4.9.3 -std=c++11 编译后的代码

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

在Linux x86_64中,Z4mainEUlvE_是给定lambda表达式的名称(mangled name),但工具无法对其进行解码。该工具只会输出输入给它的内容Z4mainEUlvE_

如何对其进行解码?


你期望的输出是什么?[]() - nwp
2
lambda:一个无名函数对象,能够捕获作用域内的变量。您想给它起什么名字? - Richard Critten
1
@richard 还有两个 lambda,当然要叫做 bob - Yakk - Adam Nevraumont
你尝试过使用带有“-t”选项的c++filt吗?如果没有,我的c++filt也无法解开你的lambda类型... - W.F.
4个回答

17
你可以使用GCC的特殊函数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}

根据文档,此函数返回一个使用std::malloc分配的C风格的以零结尾的字符串,调用者需要使用std::free进行释放。此示例使用智能指针在作用域结束时自动释放返回的字符串。


10

使用版本为 070207 20070207c++filt 工具:

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

虽然评论者已经建议过了,但这些名称并不总是完全有用。


或者你可以将程序的输出直接传输到 c++filt,例如 ./a.out | c++filt - vsoftco

2

1
你可以尝试使用boost::core::demangle,但我不知道你的结果是否会有所不同。
例如:
#include <boost/core/demangle.hpp>
#include <iostream>

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接