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

如何通过类似lock_guard的方式自动记录函数进出的source_location信息?

解决方案

方案一:RAII守卫类(无需修改return语句)

如果可以接受logExit输出的行号为函数入口的行号,那么可以用RAII类实现类似lock_guard的单行用法:

#include <source_location>
#include <iostream>
using namespace std;

void logEnter(const source_location location = source_location::current()){
  cout << "Log, entering " << location.function_name() <<" at line "<< location.line() << endl;
}

void logExit(const source_location location = source_location::current()){
  cout << "Log, exiting " << location.function_name() <<" at line "<< location.line() << endl;
}

// RAII守卫类
class LogGuard {
public:
    explicit LogGuard(const source_location loc = source_location::current())
        : loc_(loc) {
        logEnter(loc_);
    }

    ~LogGuard() {
        logExit(loc_);
    }

    // 禁止拷贝和移动,避免意外复制
    LogGuard(const LogGuard&) = delete;
    LogGuard& operator=(const LogGuard&) = delete;
private:
    source_location loc_;
};

// 使用示例
string parity(int x) {
  LogGuard guard; // 只需这一行
  if (x%2 == 0)
    return "even";
  return "odd";
}

调用parity(3)时,输出为:

Log, entering parity at line 26
Log, exiting parity at line 26

这种方案的优点是完全不用修改现有函数里的return语句,代码改动极小;缺点是logExit的行号和logEnter一致,无法追踪到具体是哪个return触发的退出。

方案二:宏替换return(保留return行号)

如果需要logExit输出对应return语句的行号,可以用宏替换原有的return关键字,自动插入logExit调用:

#include <source_location>
#include <iostream>
using namespace std;

void logEnter(const source_location location = source_location::current()){
  cout << "Log, entering " << location.function_name() <<" at line "<< location.line() << endl;
}

void logExit(const source_location location = source_location::current()){
  cout << "Log, exiting " << location.function_name() <<" at line "<< location.line() << endl;
}

// 定义宏替换return
#define RETURN(val) do { logExit(); return val; } while(0)

// 使用示例
string parity(int x) {
  logEnter(); // 进入日志
  if (x%2 == 0)
    RETURN("even"); // 替换原return
  RETURN("odd");
}

调用parity(3)时,输出和你期望的一致:

Log, entering parity at line 18
Log, exiting parity at line 21

这种方案的优点是能保留return语句的行号;缺点是需要将函数里所有的return替换为RETURN宏,改动量略大于RAII方案,但仍然是批量替换级别的操作,适合大量函数的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 11:34:54