如何在不传递__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
相关产品推荐
相关产品推荐

