[英]vector -> Usage of member functions begin() and end() vs the operator[]
[英]Shouldn't the begin() and end() functions be member functions of the template class Vector?
在第3章:C ++之旅:抽象机制的草案的第82页中 ,作者写道:
如果我们还想对Vector使用range-for循环,则必须定义合适的begin()和end()函数:
template<typename T>
T∗ begin(Vector<T>& x)
{
return &x[0]; // pointer to first element
}
template<typename T>
T∗ end(Vector<T>& x)
{
return x.begin()+x.size(); // pointer to one-past-last element
}
有了这些,我们可以写:
void f2(const Vector<string>& vs) // Vector of some strings
{
for (auto s : vs)
cout << s << ’\n’;
}
请注意,类模板Vector在草稿的第81页中定义。
为了使基于范围的工作正常,编译器需要找到合适的函数来获取迭代器。
如果使用的类型是类,则它将首先查找成员函数,该函数在该类的范围内begin
和end
。
如果类型不是类或没有此类成员函数,则通过“ 参数依赖查找”查找它们。
这就是基于范围进行C阵列工作的原因。 显然,数组不能具有成员函数,因此标准库提供了两个与此定义类似的函数:
template<typename T, size_t N>
T* begin( T(&array)[N] )
{
return array;
}
同样地end
。
从标题回答您的问题: 可以 ,但不是必须的。 您可以在与类相同的名称空间中定义自由函数,然后就会找到它们。
在这样的范围内基于:
for ( for-range-declaration : expression ) statement
标准说,如果expression是类,则编译器将查找成员( (expression).begin()
, (expression).end()
)或自由函数( begin((expression))
, end((expression))
)。类型。
因此, 您既可以提供成员函数,也可以提供自由函数 (这些函数必须在依赖于参数的查找范围内)。
C ++ 11,第6.5.4节[stmt.ranged]
这是基于标准的基于范围的操作:
for ( for-range-declaration : expression ) statement
range-init = ( expression )
{
auto && __range = range-init;
for ( auto __begin = begin-expr,
__end = end-expr;
__begin != __end;
++__begin )
{
for-range-declaration = *__begin;
statement
}
}
begin-expr
和end-expr
描述为:
如果
_RangeT
是数组类型,则begin-expr和end-expr是_ range 和 _range + _ bound ,其中 _bound是数组绑定。 如果_RangeT是未知大小的数组或类型不完整的数组,则程序格式错误 ;如果
_RangeT
是类类型,则在_RangeT类的范围内查找不合格ID的begin和end,就像通过类成员访问查找(3.4.5)一样,并且如果一个(或两个)都找到至少一个声明,则beginexpr和end-expr分别是__range.begin()和__range.end();否则, begin-expr和end-expr分别是
begin(__range)
和end(__range)
,其中begin
和end
是通过与参数相关的查找(3.4.2)查找的。 出于此名称查找的目的,名称空间std是关联的名称空间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.