编辑:此问题中描述的问题是由不合规的编译器引起的(请参阅注释中的详细信息)。
假设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.
}
}
答案 0 :(得分:3)
正确:C ++ 11 for-each循环使用for (auto i : c)
给出的以下逻辑:
如果类型是长度可以推导的数组,请使用c
和c + length
;
如果类型是包含这些成员函数的类/结构,则使用c.begin()
和c.end()
;
如果上述操作失败,请通过参数依赖查找使用begin(c)
和end(c)
。
C ++ 11 for-each循环使用std::begin
和std::end
,默认情况下转发到容器的begin
/ end
函数。这样做是为了允许例如专注于数组。这些定义需要在声明for循环的位置可见。
不隐含地包含这些功能的定义。这就是没有#include
语句的错误。
它们在<iterator>
标头中定义,当您包含<iostream>
时,它会包含在内。这就是程序在包含<iostream>
时编译的原因。
因此,编译器没有执行标准的第1步和第2步,而是依靠标准库begin / end来执行它们。