我想我没有什么要解释的,因为答案已经说明了这一点。但我可能不得不引用标准(N4885)中的这句话:
(支撑。[远程]/1:(强调我的)
The range-based for statement
for ( init-statement(opt) for-range-declaration :
for-range-initializer
) statement(possibly curly-braced)
is equivalent to:
{ // starts namespace scope of for-range-initializer
init-statement; (opt)
auto &&range = for-range-initializer ;
auto begin = begin-expr ;
auto end = end-expr ;
for ( ; begin != end; ++begin )
{
for-range-declaration = * begin ;
statement ;
}
} // ends namespace scope of for-range-initializer
where
(1.1) if the for-range-initializer is an expression, it is regarded as
if it were surrounded by parentheses (so that a comma operator cannot
be reinterpreted as delimiting two init-declarators);
(1.2) range, begin, and end are variables defined for exposition only; and
(3.1) begin-expr and end-expr are determined as follows:
(1.3.1) if the for-range-initializer is an expression of array type R,
begin-expr and end-expr are range and range+N, respectively, where N
is the array bound. If R is an array of unknown bound or an array of
incomplete type, the program is ill-formed;
(1.3.2) if the for-range-initializer is an expression of class type C,
and [class.member.lookup] in the scope of C for the names begin and
end each find at least one declaration, begin-expr and end-expr are
range.begin() and range.end(), respectively;
(1.3.3) otherwise, begin-expr and end-expr are begin(range) and
end(range), respectively, where begin and end undergo
argument-dependent lookup ([basic.lookup.argdep]).
请注意,字符串、数组和所有STL容器都是可迭代的数据结构,因此已经可以使用基于范围的for循环对它们进行迭代。为了使数据结构可迭代,它必须类似于现有的STL迭代器:
1-必须有begin和end方法对该结构进行操作,可以作为成员,也可以作为独立函数,并且返回结构的开始和结束的迭代器。
2-迭代器本身必须支持operator*()方法、operator !=()方法和operator++(void)方法,可以作为成员方法,也可以作为独立函数。
#include <iostream>
#include <vector>
#define print(me) std::cout << me << std::endl
template <class T>
struct iterator
{
iterator(T* ptr) : m_ptr(ptr) {};
bool operator!=(const iterator& end) const { return (m_ptr != end.m_ptr); }
T operator*() const { return *m_ptr; }
const iterator& operator++()
{
++m_ptr;
return *this;
}
private:
T* m_ptr;
};
template <class T, size_t N>
struct array
{
typedef iterator<T> iterator;
array(std::initializer_list<T> lst)
{
m_ptr = new T[N]{};
std::copy(lst.begin(), lst.end(), m_ptr);
};
iterator begin() const { return iterator(m_ptr); }
iterator end() const { return iterator(m_ptr + N); }
~array() { delete[] m_ptr; }
private:
T* m_ptr;
};
int main()
{
array<std::vector<std::string>, 2> str_vec{ {"First", "Second"}, {"Third", "Fourth"} };
for(auto&& ref : str_vec)
for (size_t i{}; i != ref.size(); i++)
print(ref.at(i));
//auto &&range = str_vec;
//auto begin = range.begin();
//auto end = range.end();
//for (; begin != end; ++begin)
//{
// auto&& ref = *begin;
// for (size_t i{}; i != ref.size(); i++)
// print(ref.at(i));
//}
}
这个程序的输出是:
第一个
第二个
第三
第四