如何在 C++ (gcc) 中获得完全限定的函数名称,_排除_返回类型?

2023-12-21

这个问题 https://stackoverflow.com/questions/6151558/displaying-fully-qualified-name-of-the-function描述了如何使用__PRETTY_FUNCTION__获取函数的全名,包括其返回类型、参数类型、命名空间和模板参数。

考虑以下漂亮的函数:

namespace foo {
namespace {

template<int i>
int (*bar(int (*arg)(int *)))(int *) {
    printf("%s\n", __PRETTY_FUNCTION__);

    return arg;
}

} // anonymous namespace
} // namespace foo

如果您不明白,该函数接受并返回一个指向int * -> int功能。

它漂亮的名字是,当编译时g++ (4.9),

int (* foo::{anonymous}::bar(int (*)(int*)))(int*) [with int i = 1337]

clang++ (3.5),

int (*foo::(anonymous namespace)::bar(int (*)(int *)) [i = 1337])(int *)

这些字符串非常不适合测试该函数是否是某个命名空间的一部分。有没有其他方法,或者编译器提供的库来解析这些字符串?

为了澄清一下,我宁愿有类似的东西

foo::{anonymous}::bar <I don't care about anything beyond this point>

更理想的是,我想要一种编译时方式,例如constexpr功能split(__PRETTY_FUNCTION__)产生某种列表

  • 完全限定函数名
  • 返回类型
  • arg0 的类型
  • arg1 的类型

等等,但我对完全限定的函数名称很满意。


经过更仔细的观察,我写了这段代码:

template <typename InputIterator, typename T>
InputIterator findClosing( InputIterator first, InputIterator last, T close )
{
    if (first == last)
        return last;

    auto open = *first;
    unsigned counter = 1;
    while (++first != last)
    {
        if (*first == close && --counter == 0)
            return first;
        if (*first == open)
            ++counter;
    }

    return last;
}

template <std::size_t N,
          std::size_t N2>
std::string f(char const(&str)[N], char const(&name)[N2])
{
    using namespace std;

    // Argument to isalnum must be unsigned:
    auto cond = [] (unsigned char c) {return !isalnum(c) && c != '_';};

    auto iter = str;
    for (;;++iter)
    {
        iter = search( iter, end(str),
                       begin(name), end(name)-1 );

        if (iter == end(str))
            throw invalid_argument("");

        if ((iter == begin(str)      || cond(iter[-1]))
         && (iter ==   end(str) - N2 || (cond(iter[N2-1]) && iter[N2-1] != ':')))
            break;
    }

    auto origin_iter = iter;
    while(iter != begin(str))
    {
        --iter;
        for (auto p : {"()", "{}"})
        if (*iter == p[1])
            iter = findClosing(reverse_iterator<char const*>(iter+1),
                               reverse_iterator<char const*>(begin(str)),
                               p[0]).base()-2;

        if (cond(*iter) && *iter != ':')
            return string(iter+1, origin_iter+N2-1);
    }

    return string(iter, origin_iter+N2-1);
}

它应该适用于任何函数,假设不存在不必要的空格__PRETTY_FUNCTION__ and __func__仅包含非限定函数名称。

Demo http://coliru.stacked-crooked.com/a/e1237fdf0bd06c1e.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 C++ (gcc) 中获得完全限定的函数名称,_排除_返回类型? 的相关文章

  • 删除文件的最后 10 个字符

    我想删除文件的最后 10 个字符 说一个字符串 hello i am a c learner 是文件内的数据 我只是希望该文件是 hello i am a 文件的最后 10 个字符 即字符串 c learner 应在文件内消除 解决方案 将
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • 如何从本机 C(++) DLL 调用 .NET (C#) 代码?

    我有一个 C app exe 和一个 C my dll my dll NET 项目链接到本机 C DLL mynat dll 外部 C DLL 接口 并且从 C 调用 C DLL 可以正常工作 通过使用 DllImport mynat dl
  • 从经典 ASP 调用 .Net C# DLL 方法

    我正在开发一个经典的 asp 项目 该项目需要将字符串发送到 DLL DLL 会将其序列化并发送到 Zebra 热敏打印机 我已经构建了我的 DLL 并使用它注册了regasm其次是 代码库这使得 IIS 能够识别它 虽然我可以设置我的对象
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • 使用 C# 中的 CsvHelper 将不同文化的 csv 解析为十进制

    C 中 CsvHelper 解析小数的问题 我创建了一个从 byte 而不是文件获取 csv 文件的类 并且它工作正常 public static List
  • 如何定义一个可结构化绑定的对象的概念?

    我想定义一个concept可以检测类型是否T can be 结构化绑定 or not template
  • 两个类可以使用 C++ 互相查看吗?

    所以我有一个 A 类 我想在其中调用一些 B 类函数 所以我包括 b h 但是 在 B 类中 我想调用 A 类函数 如果我包含 a h 它最终会陷入无限循环 对吗 我能做什么呢 仅将成员函数声明放在头文件 h 中 并将成员函数定义放在实现文
  • 如何在当前 Visual Studio 主机内的 Visual Studio 扩展中调试使用 Roslyn 编译的代码?

    我有一个 Visual Studio 扩展 它使用 Roslyn 获取当前打开的解决方案中的项目 编译它并从中运行方法 程序员可以修改该项目 我已从当前 VisualStudioWorkspace 成功编译了 Visual Studio 扩
  • C# 动态/expando 对象的深度/嵌套/递归合并

    我需要在 C 中 合并 2 个动态对象 我在 stackexchange 上找到的所有内容仅涵盖非递归合并 但我正在寻找能够进行递归或深度合并的东西 非常类似于jQuery 的 extend obj1 obj2 http api jquer
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • MySQL Connector C/C API - 使用特殊字符进行查询

    我是一个 C 程序 我有一个接受域名参数的函数 void db domains query char name 使用 mysql query 我测试数据库中是否存在域名 如果不是这种情况 我插入新域名 char query 400 spri
  • 指针和内存范围

    我已经用 C 语言编程有一段时间了 但对 C 语言还是很陌生 有时我对 C 处理内存的方式感到困惑 考虑以下有效的 C 代码片段 const char string void where is this pointer variable l

随机推荐