You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++20立即函数默认参数替换上下文及编译器行为合规性判定

C++20 std::source_location 编译器行为合规性判断

场景1:loc为consteval立即函数

测试代码

#include <iostream>
#include <string_view>
#include <source_location>
 
consteval auto loc(std::source_location x = std::source_location::current() ) { return x; }

void log(const std::string_view message,
         const std::source_location location = loc()) {
    std::cout << "file: "
              << location.file_name() << "("
              << location.line() << ":"
              << location.column() << ") `"
              << location.function_name() << "`: "
              << message << '\n';
}
 
template <typename T> void fun(T x) { log(x); }
 
int main(int, char*[]) {
    log("Hello world!");
    fun("Hello C++20!");
}

运行表现

  • MSVC输出符合预期,两次输出分别对应main中调用log的位置、fun中调用log的位置
  • GCC两次输出均指向loc函数的定义行

合规性结论

MSVC行为符合C++标准,GCC实现存在缺陷

按照C++标准规则,std::source_location::current()作为默认实参时,求值时机是所属函数的调用点,而非定义点。loc作为立即函数,其默认参数的求值也遵循该规则:每次log被调用触发loc()调用时,才会求值current(),取值为当前log的调用位置。GCC提前在loc定义阶段完成求值,不符合标准要求。


场景2:loc为普通非立即函数

修改点

将loc的定义改为:

auto loc(std::source_location x = std::source_location::current() ) { return x; }

运行表现

  • GCC编译通过,输出符合预期,两次输出分别对应两次log的调用位置
  • MSVC编译报错,提示std::source_location::current调用不属于常量表达式

合规性结论

GCC行为符合C++标准,MSVC实现存在缺陷

std::source_location::current()是consteval立即函数,但C++标准明确允许其作为普通函数的参数默认实参使用:该场景下默认实参在调用点求值,无需满足常量表达式要求,属于标准允许的合法例外场景。MSVC未适配该特殊规则,错误抛出编译错误,不符合标准要求。


内容的提问来源于stack exchange,提问作者Fedor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 20:24:02