繁体   English   中英

begin()和end()函数不应该是模板类Vector的成员函数吗?

[英]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页中定义。

为了使基于范围的工作正常,编译器需要找到合适的函数来获取迭代器。

  • 如果使用的类型是类,则它将首先查找成员函数,该函数在该类的范围内beginend

  • 如果类型不是类或没有此类成员函数,则通过“ 参数依赖查找”查找它们。

这就是基于范围进行C阵列工作的原因。 显然,数组不能具有成员函数,因此标准库提供了两个与此定义类似的函数:

template<typename T, size_t N>
T* begin( T(&array)[N] )
{
    return array;
}

同样地end

从标题回答您的问题: 可以 ,但不是必须的。 您可以在与类相同的名称空间中定义自由函数,然后就会找到它们。

如果它不是具有.begin().end()的数组或容器,则将通过依赖参数的name查找。

据说这里

请记住以下有关基于范围的事实:

  • 自动识别数组。

  • 识别具有.begin()和.end()的容器。

  • 使用依赖于参数的查找begin()和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-exprend-expr描述为:

  • 如果_RangeT是数组类型,则begin-exprend-expr_ range _range + _ bound ,其中 _bound是数组绑定。 如果_RangeT是未知大小的数组或类型不完整的数组,则程序格式错误

  • 如果_RangeT是类类型,则在_RangeT类的范围内查找不合格ID的begin和end,就像通过类成员访问查找(3.4.5)一样,并且如果一个(或两个)都找到至少一个声明,则beginexpr和end-expr分别是__range.begin()和__range.end();

  • 否则, begin-exprend-expr分别是begin(__range)end(__range) ,其中beginend是通过与参数相关的查找(3.4.2)查找的。 出于此名称查找的目的,名称空间std是关联的名称空间。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM