使用source_location类可以减少代码中出现__FILE__
, __FUNCTION__
, __LINE__
宏的次数。
https://zh.cppreference.com/w/cpp/utility/source_location
source_location
是表示关于源码的信息,例如文件名、行号以及函数名的类。
在头文件<source_location>
中。1
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_; // 仅为阐释
};
}
source_location
类表示关于源码的具体信息,例如文件名、行号以及函数名。以前,希望获得关于调用位置的信息(用于记录、测试或调试目的)的函数必须使用宏,以令如 __LINE__
与 __FILE__
的预定义宏于调用方的环境展开。 source_location
类提供更好的替代。2
source_location类方法 | 说明 |
---|---|
current | 构造对应调用点位置的新 source_location(公开静态成员函数) |
line | 返回此对象所表示的行号 |
column | 返回此对象所表示的列号 |
file_name | 返回此对象所表示的文件名 |
function_name | 返回此对象表示的函数名,若它存在 |
#include <iostream>
#include <string_view>
#include <source_location>
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!");
}
// info:main.cpp:15 Hello world!
一个github上面的关于gcc与clang支持的source_location。3
https://github.com/paweldac/source_location
https://github.com/5455945/cpp_demo/blob/master/C%2B%2B20/source_location/source_location.cpp
#include <iostream>
#include <string_view>
// https://github.com/paweldac/source_location
#include "source_location.hpp"
// https://zh.cppreference.com/w/cpp/header/source_location
// https://zh.cppreference.com/w/cpp/utility/source_location
void log(const std::string_view& message, const std::source_location& location = std::source_location::current())
{
std::cout << "info: "
<< location.file_name() << " "
<< location.function_name() << " "
<< location.line() << " "
<< location.column() << " "
<< message << '\n';
}
int main()
{
auto location = std::source_location::current();
std::cout << "info: " << location.file_name() << ":" << location.line() << ":"
<< location.column() << ":" << location.function_name() << ": "
<< "01 Hello World!" << std::endl;
log("02 Hello world!");
auto location2 = std::source_location::current(__FILE__, __FUNCTION__, __LINE__, 0);
std::cout << location2.file_name() << ":" << location2.line() << ":"
<< location2.column() << ":" << location2.function_name() << ": "
<< "03 Hello World!" << std::endl;
log("04 Hello world!", std::source_location::current(__FILE__, __FUNCTION__, __LINE__, 0));
return 0;
}
https://github.com/paweldac/source_location/blob/master/include/source_location/source_location.hpp
#ifndef NOSTD_SOURCE_LOCATION_HPP
#define NOSTD_SOURCE_LOCATION_HPP
#pragma once
#include <cstdint>
namespace std {
struct source_location {
public:
#if not defined(__apple_build_version__) and defined(__clang__) and (__clang_major__ >= 9)
static constexpr source_location current(const char* fileName = __builtin_FILE(),
const char* functionName = __builtin_FUNCTION(),
const uint_least32_t lineNumber = __builtin_LINE(),
const uint_least32_t columnOffset = __builtin_COLUMN()) noexcept
#elif defined(__GNUC__) and (__GNUC__ > 4 or (__GNUC__ == 4 and __GNUC_MINOR__ >= 8))
static constexpr source_location current(const char* fileName = __builtin_FILE(),
const char* functionName = __builtin_FUNCTION(),
const uint_least32_t lineNumber = __builtin_LINE(),
const uint_least32_t columnOffset = 0) noexcept
#else
static constexpr source_location current(const char* fileName = "unsupported",
const char* functionName = "unsupported",
const uint_least32_t lineNumber = 0,
const uint_least32_t columnOffset = 0) noexcept
#endif
{
return source_location(fileName, functionName, lineNumber, columnOffset);
}
source_location(const source_location&) = default;
source_location(source_location&&) = default;
constexpr const char* file_name() const noexcept
{
return fileName;
}
constexpr const char* function_name() const noexcept
{
return functionName;
}
constexpr uint_least32_t line() const noexcept
{
return lineNumber;
}
constexpr std::uint_least32_t column() const noexcept
{
return columnOffset;
}
private:
constexpr source_location(const char* fileName, const char* functionName, const uint_least32_t lineNumber,
const uint_least32_t columnOffset) noexcept
: fileName(fileName)
, functionName(functionName)
, lineNumber(lineNumber)
, columnOffset(columnOffset)
{
}
const char* fileName;
const char* functionName;
const std::uint_least32_t lineNumber;
const std::uint_least32_t columnOffset;
};
} // namespace nostd
#endif