Begin()和end()作为基于范围的for循环中的成员函数

begin() and end() as member functions in a range-based for loop

本文关键字:for 循环 成员 函数 范围 于范围 end Begin      更新时间:2023-10-16

EDIT:这个问题中描述的问题是由不兼容的编译器引起的(详见注释)。

假设Generator是一个具有成员函数begin()end()的类。我的理解是,根据c++ 11标准,在基于范围的循环中:

 Generator g; 
 for (auto el: g) ;

Generator的成员函数begin()end()将在循环中使用。

我编写了一个最小的代码来演示(如下)。但是,只有当我取消第一行的注释时,代码才能正常编译。也就是说,它只在

时起作用
   #include<iostream>

。在相反的情况下,它产生错误:

  ‘begin’ was not declared in this scope (likewise for 'end'). 

我遇到了很多问题&与新标准中基于范围的循环相关的答案,但没有看到此错误的原因。

//#include<iostream>
 class Iterator{    
 public: 
  Iterator (int i_) : i(i_) 
  {}
  bool operator!=(const Iterator &other) const {
    return i != other.i;
  }
  int operator*() const{
    return i; 
  }
  void operator++(){
    ++i;
  }
private:
  int i; 
};
struct Generator{
  Iterator begin()
  {
    return Iterator(0); 
  }
  Iterator end(){
    return Iterator(100); 
  }
}; 

int main(){
  Generator g; 
  for (int i : g)
    {
      // do something. 
    }
}

更正: c++ 11 for-each循环使用给定for (auto i : c)的以下逻辑:

  1. 如果类型是长度可推导的数组,则使用cc + length;

  2. 如果类型是包含这些成员函数的类/结构,则使用c.begin()c.end();

  3. 使用begin(c)end(c)通过参数依赖查找如果上述失败

c++ 11 for-each循环使用std::beginstd::end,默认情况下转发到容器的begin/end函数。这样做是为了允许对数组进行专门化。这些定义需要在声明for循环时可见。

这些函数的定义没有隐式包含。这就是为什么没有#include语句就会出现错误的原因。

它们在<iterator>头文件中定义,在包含<iostream>时包含。这就是当包含<iostream>时程序编译的原因。

因此,编译器不执行标准的步骤1和2,而是依靠标准库begin/end来执行它们。