[support.srcloc]介绍source_location::current
:
对它的任何调用都
current
显示为默认参数 ([dcl.fct.default]) 或其子表达式,应对应于使用默认参数 ([expr.call]) 的函数的调用位置。
请注意,“默认参数([dcl.fct.default])”包括默认模板参数,但上面的引用只提到了“函数调用的位置”。source_location::current()
在默认模板参数的上下文中进行评估是否合法?
考虑这段代码(现场演示):
#include <iostream>
//#include <source_location>
#include <experimental/source_location>
//using source_location = std::source_location;
using source_location = std::experimental::source_location;
struct literal {
char data[64] = {'\0'}; // For simplicity, assume it is large enough to hold all possible values.
constexpr literal(const char* src) {
char* dst = &data[0];
while(*src) *(dst++) = *(src++);
*dst = '\0';
}
};
struct location { // A structural type is needed since source_location is not a structural type.
literal file;
literal func;
unsigned line;
unsigned column;
constexpr location(const char* file, const char* func, unsigned line, unsigned column)
: file(file), func(func), line(line), column(column) {}
constexpr location(const source_location& loc)
: location(loc.file_name(), loc.function_name(), loc.line(), loc.column()) {}
};
template<location loc = source_location::current()> // line 30
void print() {
std::cout << loc.file.data << ' ' << loc.func.data << ' ' << loc.line << ' ' << loc.column << std::endl;
}
void caller_1() {
print(); // line 36
}
void caller_2() {
print(); // line 40
}
int main() {
caller_1();
caller_2();
return 0;
}
clang 编译失败,报错:
错误:抱歉,“位置”类型的非类型模板参数尚不支持
gcc 使它被编译但给出了奇怪的结果function_name()
并line()
指示不同的位置:
./example.cpp caller_1 30 0
./example.cpp caller_2 30 0