Mar*_*dun 6 c++ constexpr c++20 consteval
在下面的代码中,如果here()停止consteval(完整 RT 或constexpr),则line()是f()inside的调用行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();
}
Run Code Online (Sandbox Code Playgroud)
这是我的理解:
默认参数在调用站点替换并在每次调用时进行评估。请参阅以下代码作为示例:
#include <iostream>
int count() {
static int counter = 0;
return ++counter;
}
void foo(int value = count())
{
std::cout << value << "\n";
}
int main()
{
foo();
foo();
}
Run Code Online (Sandbox Code Playgroud)
输出是
1
2
Run Code Online (Sandbox Code Playgroud)
这证明count()已被调用两次,并且main()主体实际上相当于:
1
2
Run Code Online (Sandbox Code Playgroud)
现在让我们回到你的例子。如果here()不是consteval,那么您的调用f()相当于,而这f(here())又相当于f(here(std::experimental::source_location::current())),这将返回调用的行f(),即是17。
然而,如果here()is consteval,当编译器读取 的声明时f(),它必须立即计算here()which 返回某个此时等于std::experimental::source_location的line()值(为了解释的目的,我们称其为),因此当您调用 时,默认参数已经被计算为,并且该调用实际上相当于10default_locationf()default_locationf(default_location)