You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++(Clang/GCC)非静态类方法获取调用方完整函数签名方案

问题目标

实现C++类的非静态成员方法,获取调用该方法的函数完整签名,效果与调用方本地使用__PRETTY_FUNCTION__宏获取的自身函数签名完全一致。

现状与预期

现有测试代码为MyClass::foo设置默认参数const char* parent = __builtin_FUNCTION(),运行后输出行2仅能得到调用方的短函数名bar,期望输出行2与输出行3格式一致,即获取到完整签名void Space::bar(int)。

限制条件
  • MyClass::foo不允许定义为静态方法
  • 无法通过类声明后定义#define foo() MyClass::foo(__PRETTY_FUNCTION__)这类宏传参的静态方案解决问题
测试代码
#include <iostream>

class MyClass {
public:
    void foo(const char* parent = __builtin_FUNCTION()) {
        std::cout << "1: " << __PRETTY_FUNCTION__ << std::endl;
        std::cout << "2: " << parent << std::endl;
    }
};

namespace Space
{
    void bar(int notUsedParam){
        MyClass myClass;
        myClass.foo();
        std::cout << "3: " << __PRETTY_FUNCTION__ << std::endl;
    }
}

int main() {
    Space::bar(1);
    return 0;
}
当前运行输出
1: void MyClass::foo(const char*)
2: bar
3: void Space::bar(int)
实现方案

直接将默认参数里的__builtin_FUNCTION()替换为__PRETTY_FUNCTION__即可,不需要修改方法的非静态属性,也不需要调整调用方代码、新增包裹宏。
修改后的MyClass定义:

class MyClass {
public:
    void foo(const char* parent = __PRETTY_FUNCTION__) {
        std::cout << "1: " << __PRETTY_FUNCTION__ << std::endl;
        std::cout << "2: " << parent << std::endl;
    }
};

修改后运行输出完全匹配预期:

1: void MyClass::foo(const char*)
2: void Space::bar(int)
3: void Space::bar(int)

跨编译器适配说明:GCC、Clang下使用__PRETTY_FUNCTION__,MSVC编译器下替换为__FUNCSIG__即可,行为完全一致。

原理说明

函数签名相关内置宏的求值规则为:在哪个源码位置完成求值,就返回对应位置的上下文信息。C++标准规定默认参数的求值发生在调用方的调用表达式位置,而非被调用函数的定义位置,因此写在默认参数位的__PRETTY_FUNCTION__会直接捕获调用方的完整函数签名,完全满足需求。
之前使用__builtin_FUNCTION()只能拿到短函数名,是这个内置函数本身的设计特性——它仅返回裸函数名,不包含命名空间、返回值、参数列表等完整签名信息。

内容的提问来源于stack exchange,提问作者Oshio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 03:12:23