组合ranges适配器与std::source_location出现异常结果问题咨询
结论
你提供的代码不符合C++标准规范,两个编译器的表现均不构成标准违反,其中MSVC的编译报错符合标准要求,GCC能编译通过属于其实现的约束校验疏漏。
具体解释
- 首先
std::views::transform要求传入的可调用对象必须满足std::invocable<F, T>约束,其中T是输入range的元素类型(此处为int)。而std::invocable的约束检查不考虑函数/ lambda的默认实参:默认实参不属于函数类型的一部分,仅在直接以函数名调用时生效,std::invoke(ranges内部调用可调用对象的底层实现)不会自动补全默认实参,因此你的lambda(需要两个入参)并不满足单int参数的调用要求,程序本身是 ill-formed 的,MSVC的编译报错是正确的。 - 即便部分编译器(如你测试的GCC版本)疏漏了约束检查允许代码编译,运行结果也符合标准规定:
std::source_location::current()的求值位置是它所在的函数调用点,也就是GCC标准库内部transform_view迭代器解引用时调用lambda的代码行,你看到的固定输出61就是该内部调用语句的行号,而非你定义lambda的代码行号,该表现完全符合std::source_location的语义要求。
如果你想要获得lambda定义位置的行号,应该直接在lambda定义的外层作用域求值
std::source_location::current(),再捕获到lambda中使用,而不是将其作为默认实参。
内容的提问来源于stack exchange,提问作者康桓瑋
相关产品推荐
相关产品推荐

