基于范围的语句定义冗余 [英] Range-based for statement definition redundancy

查看:124
本文介绍了基于范围的语句定义冗余的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

查看n3092,在§6.5.4中,我们找到了一个基于范围的for循环的等价。然后继续说 __ begin __ end 等于。它区分数组和其他类型,我发现这是多余的(也令人困惑的)。

Looking at n3092, in §6.5.4 we find the equivalency for a range-based for loop. It then goes on to say what __begin and __end are equal to. It differentiates between arrays and other types, and I find this redundant (aka confusing).

它说的数组类型 __ begin __ end 是你期望的:指向第一个的指针和指向一个超过结束的指针。对于其他类型, __ begin __ end 等于 begin(__ range) end(__ range)与ADL。为了找到 std :: begin std ::,命名空间 std

It says for arrays types that __begin and __end are what you expect: a pointer to the first and a pointer to one-past the end. Then for other types, __begin and __end are equal to begin(__range) and end(__range), with ADL. Namespace std is associated, in order to find the std::begin and std::end defined in <iterator>, §24.6.5.

< iterator> 如果我们看一下 std :: begin std :: end 的定义,它们都被定义为数组以及容器类型。数组版本的作用和上面的完全一样:指向第一个的指针,指向一个超过结束的指针。

However, if we look at the definition of std::begin and std::end, they are both defined for arrays as well as container types. And the array versions do exactly the same as above: pointer to the first, pointer to one-past the end.

为什么需要区分数组和其他类型,当为其他类型给出的定义也可以工作时,找到 std :: begin std :: end

Why is there a need to differentiate arrays from other types, when the definition given for other types would work just as well, finding std::begin and std::end?

为方便起见,使用了一些简短的引号:


§6.5.4基于范围的 for 语句



- 如果_RangeT是一个数组类型,begin-expr和end-expr分别是__range和__range + __bound,其中__bound是数组绑定。如果_RangeT是未知大小的数组或不完全类型的数组,则程序未生成。

§6.5.4 The range-based for statement

— if _RangeT is an array type, begin-expr and end-expr are __range and __range + __bound, respectively, where __bound is the array bound. If _RangeT is an array of unknown size or an array of incomplete type, the program is ill-formed.

- 否则,begin-expr和end-expr分别是begin(__ range)和end(__ range),其中begin和end是通过参数相关的查找(3.4.2)。对于此名称查找,命名空间std是关联的命名空间。

— otherwise, begin-expr and end-expr are begin(__range) and end(__range), respectively, where begin and end are looked up with argument-dependent lookup (3.4.2). For the purposes of this name lookup, namespace std is an associated namespace.

b
$ b


§24.6.5范围访问



§24.6.5 range access

template <class T, size_t N> T* begin(T (&array)[N]);

返回:array。

template <class T, size_t N> T* end(T (&array)[N]);

返回:array + N。

Returns: array + N.


推荐答案

这避免了使用ADL的情况:

This avoids a corner-case with ADL:

namespace other {
  struct T {};
  int begin(T*) { return 42; }
}

other::T a[3];
for (auto v : a) {}

因为ADL找到其他:: begin调用 begin(a),等效的代码将会导致一个混乱的编译错误(沿着can not compare int to other :: T * c $ c> end(a)会返回一个T *)或不同的行为(如果其他:: end被定义,并且做了一些意想不到的事情)。

Because ADL finds other::begin when calling begin(a), the equivalent code would break causing a confusing compile error (along the lines of "can't compare int to other::T*" as end(a) would return a T*) or different behavior (if other::end was defined and did something likewise unexpected).

这篇关于基于范围的语句定义冗余的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆