gpt4 book ai didi

c++ - 结合范围适配器和 std::source_location 得到奇怪的结果

转载 作者:行者123 更新时间:2023-12-04 07:14:58 26 4
gpt4 key购买 nike

考虑 following useless code :

#include <ranges>
#include <source_location>
#include <iostream>

int main() {
auto lines = std::views::iota(0, 5)
| std::views::transform(
[](int, const std::source_location& location = std::source_location::current())
{ return location.line(); }
);
for (const auto& line : lines)
std::cout << line << "\n";
}
MSVC 拒绝并显示奇怪的错误消息:
(7): error C2676: binary '|': 'std::ranges::iota_view<_Ty1,_Ty2>' does not define this operator or a conversion to a type acceptable to the predefined operator
with
[
_Ty1=int,
_Ty2=int
]
并且 GCC 输出奇怪的行号 61无论 std::source_location::current()是哪一行位于:
61
61
61
61
61
上面的代码格式正确吗?如果是这样,是否意味着 MSVC 和 GCC 都有错误?

最佳答案

gcc 是正确的,程序是完全有效的。

And GCC outputs strange line number 61 no matter which row the std::source_location::current() is in:


这是因为默认函数参数 current() , 在函数调用时求值,这与函数的声明位置无关。
该函数由 transform_view 调用的 iteratoroperator*() .但不是直接由 operator*() , 该运算符(operator)将调用 invoke它本身必须做大量工作以确保正确调用它。以及 libstdc++ 的 invoke 实现中的实际最终重载被调用的是...哦,看那个,它是 bits/invoke.h:61 :
template<typename _Res, typename _Fn, typename... _Args>
constexpr _Res
__invoke_impl(__invoke_other, _Fn&& __f, _Args&&... __args)
{ return std::forward<_Fn>(__f)(std::forward<_Args>(__args)...); }


如果不只是打印 source_location 的行号,这将更容易发现。给你,你还打印了文件名:
auto lines = std::views::iota(0, 5)
| std::views::transform(
[](int, const std::source_location& location = std::source_location::current())
{ return fmt::format("{}:{}", location.file_name(), location.line()); }
);

fmt::print("{}\n", lines);
打印包含字符串 /opt/compiler-explorer/gcc-trunk-20210817/include/c++/12.0.0/bits/invoke.h:61 的范围, 五次。

关于c++ - 结合范围适配器和 std::source_location 得到奇怪的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68821113/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com