无需宏:实现C++类实例化时源码行的常量表达式记录
无需宏实现编译时自动记录源码行的类模板
问题背景
需要实现一个类模板,在实例化时无需显式指定参数,就能以编译时常量记录当前源码行号,替代原有的宏实现方案。
解决方案(C++20)
利用C++20的auto非类型模板参数和std::source_location默认参数的求值特性,可以直接实现需求:
模板定义
#include <iostream> #include <source_location> template<typename T, auto Line = std::source_location::current().line()> struct A { static constexpr auto line() { return Line; } };
使用示例
int main() { A<double> a; A<double> b; if constexpr(a.line() != b.line()) { std::cout << a.line() << std::endl; std::cout << b.line() << std::endl; } }
原理说明
- auto非类型模板参数:C++20允许用
auto推导非类型模板参数的类型,这里Line会被自动推导为int(匹配std::source_location::line()的返回类型)。 - std::source_location的求值时机:当
std::source_location::current()作为模板默认参数时,它会在模板实例化的位置求值,而非模板定义的位置。因此,不同行的A<double>实例化会生成不同的模板特化,各自持有对应行号的编译时常量。 - 该方案完全替代了原宏的功能,无需任何预处理指令,代码更简洁且符合C++标准语法。
内容的提问来源于stack exchange,提问作者davidhigh
相关产品推荐
相关产品推荐

