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

如何在不传递__FILE__及预处理技巧的情况下,打印外部函数调用者的文件名?

问题解答:无需显式传递__FILE__和预处理技巧,打印调用者源文件名

问题描述

能否在不显式传递__FILE__且不使用预处理技巧的情况下,打印调用外部文件中定义函数的调用者源文件名?

现有代码示例:

Header.h

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

void Log1(string msg) {
   cout << __FILE__ << msg << endl;   // 输出 "Header.h"
}

void Log2(string file, string msg) {
   cout << file << msg << endl;
}

inline void Log3(string msg) {
   cout << __FILE__ << msg << endl;   // 输出 "Header.h"
}

Source.cpp

#include "Header.h"

int main()
{    
    Log1(" Test 1");
    Log2(__FILE__, " Test 2");
    Log3(" Test 3");
}

现有输出:

pathTo\Header.h Test 1
pathTo\Source.cpp Test 2
pathTo\Header.h Test 3

预期Log3的输出:pathTo\Source.cpp Test 3


解决方案

在C++20及以上标准中,可通过std::source_location实现需求,无需显式传递__FILE__或使用预处理技巧:

修改后的Header.h

#include <iostream>
#include <string>
#include <source_location> // 引入C++20标准头文件
using namespace std;

void Log1(string msg) {
    cout << __FILE__ << msg << endl; // 仍输出Header.h
}

void Log2(string file, string msg) {
    cout << file << msg << endl;
}

// 新增默认参数,利用source_location捕获调用点信息
void Log3(string msg, const source_location& loc = source_location::current()) {
    cout << loc.file_name() << msg << endl; // 获取调用者的源文件名
}

运行输出

pathTo\Header.h Test 1
pathTo\Source.cpp Test 2
pathTo\Source.cpp Test 3

原理说明

  • std::source_location::current()是C++20引入的标准库功能,会在函数调用点捕获源文件、行号等编译期信息,默认参数的求值时机是调用时,因此能正确获取调用者的文件名。
  • 旧版本C++(C++20之前)无法实现该需求:因为运行时不会保留调用点的源文件路径信息,必须依赖预处理阶段将__FILE__嵌入代码,要么显式传递,要么用预处理宏包装函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 18:35:41