C++20推出了source_location
类,用于记录文件名、行号以及函数名。在C++20之前,一般使用 __FILE__
、 __LINE__
、__FUNCION__
的预定义宏调用方式。
source_location 的声明很简单,一个静态成员函数返回当前行的信息,一个构造函数,其余是返回数据成员的函数。
namespace std {
struct source_location {
// 静态函数
static consteval source_location current() noexcept;
// 构造
constexpr source_location() noexcept;
// 成员访问
constexpr uint_least32_t line() const noexcept;
constexpr uint_least32_t column() const noexcept;
constexpr const char* file_name() const noexcept;
constexpr const char* function_name() const noexcept;
private:
uint_least32_t line_; // 行号
uint_least32_t column_; // 列号
const char* file_name_; // 文件名
const char* function_name_; // 函数名
};
}
用法很简单,一般使用场景用于日志输出,如:
void log(std::string_view message,
const std::source_location& location = std::source_location::current())
{
std::cout << "info:"
<< location.file_name() << ':'
<< location.line() << ' '
<< message << '\n';
}
int main()
{
log("Hello world!");
}
source_location 是一个很简单的类,其核心是利用了__builtin_FILE()
、__builtin_FUNCTION()
、__builtin_LINE()
、__builtin_COLUMN()
。(相关资料:https://gcc.gnu.org/onlinedocs/gcc-4.8.0/gcc/Other-Builtins.html#index-g_t_005f_005fbuiltin_005fFILE-3359)
这里个人进行了一些简化,未考虑编译器的兼容,同时current()
与std
不同,自行实现版本:
struct source_location {
constexpr source_location(const char* file_name = __builtin_FILE(),
const char* function_name = __builtin_FUNCTION(),
unsigned int line = __builtin_LINE()) noexcept
: file_name_(file_name), function_name_(function_name), line_(line) {}
static constexpr source_location current() noexcept { return sourc_location(); }
constexpr const char* file_name() const noexcept { return file_name_; }
constexpr const char* function_name() const noexcept { return function_name_; }
constexpr unsigned int line() const noexcept { return line_; }
private:
const char* file_name_;
const char* function_name_;
const unsigned int line_;
};
接下来,看看怎么用:
source_location location;
std::cout << "info: " << location.file_name() << ":" << location.line() << ":"
<< location.column() << ":" << location.function_name() << ": "
<< "01 Hello World!" << std::endl;
其他实现版本:source_location (github.com)