参考源码的实现

参考 gcc 和 mscv 的实现会发现内部依靠的是一些与 builtin 相关的内建函数。

注意所有内建函数均已具体编译器和平台而不同。

下方代码在笔者的 x86,windows 平台的 mscv 和 gcc 中可以通过:

namespace my {
class source_location {
public:
    using sequence_type = int;

private:
    const char*   m_file = "";
    const char*   m_func = "";
    sequence_type m_line{};
    sequence_type m_column{};

public:
    static source_location current(
        const char* const   file = __builtin_FILE(),
        const char* const   func = __builtin_FUNCTION(),
        const sequence_type line = __builtin_LINE(),
#ifdef _MSC_VER
        const sequence_type column = __builtin_COLUMN()
#else
        const sequence_type column = 0
#endif
        ) noexcept {
        source_location ret;
        ret.m_line   = line;
        ret.m_column = column;
        ret.m_file   = file;
        ret.m_func   = func;
        return ret;
    }

public:
    constexpr source_location() noexcept = default;

    constexpr sequence_type line() const noexcept {
        return m_line;
    }
    constexpr sequence_type column() const noexcept {
        return m_column;
    }
    constexpr const char* file_name() const noexcept {
        return m_file;
    }
    constexpr const char* function_name() const noexcept {
        return m_func;
    }
};
}  // namespace my

#include <iostream>
#include <string>

bool log(const std::string& msg = ""
         , const my::source_location location = my::source_location::current()
         ) {
    std::cout << "File: " << location.file_name() << std::endl;
    std::cout << "Fun: " << location.function_name() << std::endl;
    std::cout << "Line: " << location.line() << std::endl;
    std::cout << "Column: " << location.column() << std::endl;
    std::cout << "Msg: " << msg << std::endl;

    return true;
}

const bool flag = log();

int main() {
    log("Hello world!");
}

其实多数编译器在 C++20 标准发布前就已经存在了这些内置指令,所以即使你的编译器不支持 C++20,也可以自行查看是否存在这些内置的指令函数,并使用它。

GCC 11.2.0 MinGW-W64

File: main.cpp
Fun:
Line: 17
Column: 22
Msg:
File: main.cpp
Fun: int main()
Line: 20
Column: 8
Msg: Hello world!

MSVC V19.29

File: E:\vs-2019\SolutionName\Latest\main.cpp
Fun:
Line: 17
Column: 19
Msg:
File: E:\vs-2019\SolutionName\Latest\main.cpp
Fun: main
Line: 20
Column: 5
Msg: Hello world!

关于文件名是否包含路径问题,可能受到编译时的执行路径问题,我们暂不关心差别。

而这里的函数名和列号两者均不相同,可见这部分的内容虽然标准给出了行为规定,但是具体实现还是有差别的。

更多推荐