C++11首次引入了基于区间(范围)的for循环
range-for
for ( range_declaration : range_expression ) loop_statement
其定义如下
{
auto && __range = range_expression ;
for (auto __begin = begin_expr, __end = end_expr;
__begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
和传统for循环不同,这种基于区间的for循环可以在区间的元素上直接迭代:
std::vector<int> v = {1, 2, 3, 4};
for (int i : v)
std::cout << i << " ";
按照定义,编译器内部会把这段代码扩展成:
std::vector<int> v = {1, 2, 3, 4};
{
auto && __range = v ;
for (auto __begin = v.begin(), __end = v.end();
__begin != __end; ++__begin) {
int i = *__begin;
std::cout << i << " ";
}
}
C++17将其定义修改为
{
auto && __range = range_expression ;
auto __begin = begin_expr ;
auto __end = end_expr ;
for ( ; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
从而引来了如下问题:
How the new range-based for loop in C++17 helps Ranges TS?
#include <iostream>
#include <string>
// a struct to get the first word of a string
struct FirstWord {
std::string data;
// declare a predicate to make ' ' a string ender
struct EndOfString {
bool operator()(std::string::iterator it) { return (*it) != '\0' && (*it) != ' '; }
};
std::string::iterator begin() { return data.begin(); }
EndOfString end() { return EndOfString(); }
};
// declare the comparison operator
bool operator!=(std::string::iterator it, FirstWord::EndOfString p) { return p(it); }
// test
int main() {
for (auto c : {"Hello World !!!"})
std::cout << c;
std::cout << std::endl; // print "Hello World !!!"
for (auto c : FirstWord{"Hello World !!!"}) // works with gcc with C++17 enabled
std::cout << c;
std::cout << std::endl; // print "Hello"
}