c++ - 如何使用 __LINE__ 或其他方法从调用站点获取行号?

标签 c++ visual-studio-2017 macros preprocessor line-numbers

考虑一下我写的这个简短的程序:

    #include <iostream>
    
    template<bool Debug = false>
    constexpr int add(const int& a, const int& b) { 
        if (Debug)
            std::cout << __FUNCTION__ << " called on line " << __LINE__ << '\n';
        return (a + b);
    }
    
    int main() {
        std::cout << add(3, 7) << '\n';
        std::cout << add<true>(5, 9) << '\n';
        return 0;
    }
它工作得很好,并且提供了正确的输出:
10
add called on line 6
14
但是,我希望打印的行号是程序调用站点上的行,在该程序中应该是第 12 行。
那么我该如何使用 __LINE__或者其他一些方法来给我调用函数的行号?
所需的输出是:
10
add called on line 12
14
如果可能,我希望它从函数本身生成。

-编辑-
作为对读者的说明,我对任何和所有选项都持开放态度,但对于我当前的构建环境,我仅限于 C++17,并且我正在使用 Visual Studio。

最佳答案

你可以这样称呼它:

template<bool Debug = false>
constexpr int add(const int& a, const int& b, int loc = __LINE__) { 
    if (Debug)
        std::cout << __FUNCTION__ << " called on line " << loc << '\n';
    return (a + b);
}

int main() {
    std::cout << add(3, 7) << '\n';
    std::cout << add<true>(5, 9, __LINE__) << '\n';
    return 0;
}
输出:
10
add called on line 14
14

此外,您可以定义一个宏来跳过第三个参数:
#define add_Debug(a, b) add<true>(a,b,__LINE__)

C++ 20 及更高版本
使用 C++20,我们得到 std::source_location 其中包含有关行号、函数、文件名的信息。如果您的编译器支持它,您可以使用它。示例(使用 g++ 9.3.0 测试)。您将不再需要宏:
#include <iostream>
#include <experimental/source_location>

using source_location = std::experimental::source_location;

template<bool Debug = false>
constexpr int add(const int& a, const int& b, source_location l = source_location::current()) { 
    if (Debug)
          // this will print 'main' as function name
          //std::cout << l.function_name() << " called on line " << l.line() << //'\n';
        std::cout << source_location::current().function_name() << " called on line " << l.line() << '\n';


    return (a + b);
}

int main()
{
    std::cout << add(3, 7) << '\n';
    std::cout << add<true>(5, 9) << '\n';

    return 0;
}
输出:
10
add<true> called on line 16
14
source_location你不必再使用宏了。它将正确打印该行

关于c++ - 如何使用 __LINE__ 或其他方法从调用站点获取行号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62869821/

相关文章:

c++ - C++中相同指针的两个优先级队列

c++ - strstr 总是返回 null

c# - 如何在 Visual Studio 中(重新)启用实时 CSS 编辑?

uwp - 通过App Installer安装UWP应用程序出现网络错误,依赖包丢失

c++ - 使用具有设置延迟 C++ 的 mouse_event 平滑鼠标移动

C++使用SFINAE检测任何构造函数

c++ - 在 Mac OS X 上使用 EWS SDK Linux 加载 ecw 文件 -> 错误链接符号

Azure Function App 在发布后无法运行,但可以在本地通过 VS2017 运行

迭代 undefined symbol 的宏

c++ - Dynamic#include 基于宏定义