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

时间:2014-03-20 09:55:58

标签: c++ c++11

编辑:此问题中描述的问题是由不合规的编译器引起的(请参阅注释中的详细信息)。

假设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'). 

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

//#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. 
    }

}

1 个答案:

答案 0 :(得分:3)

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

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

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

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

  4. C ++ 11 for-each循环使用std::beginstd::end,默认情况下转发到容器的begin / end函数。这样做是为了允许例如专注于数组。这些定义需要在声明for循环的位置可见。

    不隐含地包含这些功能的定义。这就是没有#include语句的错误。

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

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