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

source_location调用结果存差异,C++标准规定的正确结果(含wrapper)是什么?

C++标准下source_location的正确行为分析

测试代码

// Preamble
#include <iostream>
#include <source_location>

// Using a function
constexpr std::size_t function(
    std::size_t line = std::source_location::current().line()
) noexcept {return line;}

// Using a constructor
struct construction {
    constexpr construction(
        std::size_t input = std::source_location::current().line()
    ) noexcept: line{input} {}
    std::size_t line;
};

// Using a template deduction guide
template <std::size_t Line>
struct wrapper {
    static constexpr std::size_t line = Line;
};
template <std::size_t index = std::source_location::current().line()>
wrapper() -> wrapper<index>;

// Main
int main(int argc, char* argv[]) {
    std::size_t f1 = function();
    std::size_t f2 = function();
    std::size_t c1 = construction().line;
    std::size_t c2 = construction().line;
    std::size_t w1 = wrapper().line;
    std::size_t w2 = wrapper().line;
    std::cout << f1 << " " << f2 << std::endl;
    std::cout << c1 << " " << c2 << std::endl;
    std::cout << w1 << " " << w2 << std::endl;
    return 0;
}

不同编译器输出

// GCC 12.2
28 29 // NOT EQUAL
30 31 // NOT EQUAL
23 23 // EQUAL

// CLANG 15.0
7 7   // EQUAL 
13 13 // EQUAL
23 23 // EQUAL

标准规定的正确输出

根据C++20及后续标准的规定,正确输出应与GCC的结果一致:

  • f1和f2分别对应调用function()的行号(代码第28、29行),输出28 29
  • c1和c2分别对应调用construction()的行号(代码第30、31行),输出30 31
  • w1和w2为同一个值,即推导指南定义所在的行号(代码第23行),输出23 23

规则细节解释

  1. 函数/构造函数的默认参数:
    std::source_location::current()作为函数默认参数时,求值时机是每次函数被调用时,会获取当前调用语句所在的行号。因此每次调用function()或construction(),都会取对应调用行的行号,所以f1≠f2、c1≠c2,GCC的行为符合标准,Clang此处处理有误。

  2. 模板推导指南的默认模板参数:
    模板推导指南中的默认模板参数,求值时机是模板首次被实例化时,而非每次调用。这里wrapper()推导指南里的index默认值,会在第一次创建wrapper对象时,取推导指南定义所在的行号(第23行),后续所有wrapper()调用都会复用该实例化结果,因此w1和w2值相同,GCC与Clang的这部分行为都符合标准。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 08:30:49