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

huangapple go评论106阅读模式
英文:

Does std::ranges::views::enumerate use the wrong type for indexing on GCC?

问题

首先,使用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)>);

这对我来说是有道理的,因为根据我所理解的,std::size_t 是用于索引对象的正确类型。

然后,使用C++20的范围,静态断言失败。相反,以下内容通过了:

static_assert(std::is_same_v<long, decltype(x)>);

但是在我的系统上,longstd::size_t 不同,我验证了以下内容:

static_assert(std::is_same_v<unsigned long, std::size_t>)

在GCC 13.2.1上,这是示例

英文:

First, using Range-v3, I noticed that

std::vector&lt;int&gt; v;
auto w = v | ranges::views::enumerate;
auto [x, y] = *w.begin();
static_assert(std::is_same_v&lt;std::size_t, decltype(x)&gt;);

which makes sense to me because std::size_t is the right type to use for indexing into objects, as far as I've understood.

Then, with C++20 ranges, the static assertion fails. Instead, the following passes,

static_assert(std::is_same_v&lt;long, decltype(x)&gt;);

but long is not the same as std::size_t on my system, where I verified that

static_assert(std::is_same_v&lt;unsigned long, std::size_t&gt;)

On, GCC 13.2.1, here's the example.

答案1

得分: 4

No.

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 是无符号的。

英文:

> Does std::ranges::views::enumerate use the wrong type for indexing on GCC?

No.

std::views::enumerate is specified to use range_difference_t&lt;Base&gt; as its index value. gcc implementation is correct to the specification.

On the other hand, range-v3's implementation used make_unsigned&lt;range_difference_t&lt;Base&gt;&gt; as its index value.

Signed seems like a much better choice here, given that you probably want subtraction to be sensible. Although there's no discussion of this choice as far as I can see in P2164 (or any revision thereof).


> but long is not the same as std::size_t on my system

long is not the same as std::size_t on any system. long is signed and size_t is unsigned.

huangapple
  • 本文由 发表于 2023年8月4日 01:37:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76830410.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定