std::ranges::views::enumerate 在 GCC 上建立索引时是否使用了错误的类型?

Enr*_*lis 5 c++ size-t language-lawyer std-ranges c++23

首先,使用 Range-v3,我注意到

std::vector<int> v;
auto w = v | ranges::views::enumerate;
auto [x, y] = *w.begin();
static_assert(std::is_same_v<std::size_t, decltype(x)>);
Run Code Online (Sandbox Code Playgroud)

这对我来说很有意义,因为std::size_t据我所知,这是用于索引对象的正确类型

然后,对于 C++20 范围,静态断言会失败。相反,以下传递,

static_assert(std::is_same_v<long, decltype(x)>);
Run Code Online (Sandbox Code Playgroud)

但与我的系统上long的不一样,我在其中验证了这一点std::size_t

static_assert(std::is_same_v<unsigned long, std::size_t>)
Run Code Online (Sandbox Code Playgroud)

在 GCC 13.2.1 上,这是示例

Bar*_*rry 5

GCC 上的索引是否std::ranges::views::enumerate使用了错误的类型?

不。

std::views::enumerate指定用作range_difference_t<Base>其索引值。gcc 实现符合规范。

另一方面,range-v3 的实现 用作 make_unsigned<range_difference_t<Base>>其索引值。

考虑到您可能希望减法是明智的,有符号在这里似乎是一个更好的选择。尽管据我在P2164(或其任何修订版)中所见,没有对此选择进行讨论。


但与我的系统上long的不一样std::size_t

longstd::size_t与任何系统上的都不一样。long已签名和size_t未签名。