【发布时间】:2020-10-19 15:18:57
【问题描述】:
在下面的代码中,如果here() 不再是consteval(完整的RT 或constexpr),那么line() 是f() 在main() 内的调用行。但是consteval 是f() 的定义。这种差异从何而来?
#include <experimental/source_location>
#include <iostream>
consteval std::experimental::source_location here(
std::experimental::source_location loc = std::experimental::source_location::current())
{
return loc;
}
void f(const std::experimental::source_location& a = here())
{
std::cout << a.line() << std::endl; // will either print 17, or 10
}
int main()
{
f();
}
【问题讨论】:
-
在调用站点替换默认参数(如果使用)。如果表达式已经被 constevaled,那么无论调用站点如何,它都将具有相同的值,可以说?因为不同的翻译单元可能会调用相同的
f函数。这将松散/不好地解释为什么,但我同意这会令人惊讶。 -
请务必注意,您正在尝试执行的操作(将
source_location::current替换为与之等效的内容)不起作用。这个函数假定总是返回source_location::current所在的代码位置,而不是调用它的位置。 any 调用here的正确答案应该是第 4 行。没有办法让您尝试做的工作;您必须从您希望获取当前位置的位置准确调用该函数。 -
根据我自己的实验,GCC 尚未很好地实现源位置。 consteval 与否,您可能会发现报告的源代码行的变体。
-
@NicolBolas,试试godlink,将
consteval替换为constexpr(或完全删除)并查看变化。现在here()变成source_location::current()的别名——我的理解是它发生因为a = here()在调用f()时被评估,而f()又在同一个地方评估loc = source_location::current(),然后使用来自少数内置的内在“函数”的值评估current()的所有默认参数。 -
@Oliv,GCC/Clang
__builtin_FILE/_FUNCTION/_LINE已经存在一段时间了,source_location::current是一种标准化它们的方式...
标签: c++ constexpr c++20 consteval