Intro
C++ 11으로 넘어오면서 다른 언어가 가진 foreach 개념이 C++에도 도입되었다.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
int x[3] = { 1,2,3 };
vector<int> v = { 1,2,3,4,5 };
// 기존(C++ 98)의 for loop
for (int i=0; i< 3;++)
{
cout << x[i] << endl;
}
// C++ 11부터 도입된 range-based for loop
for (auto/*data type*/ n : x)
{
cout << n << endl;
}
// 배열뿐만 아니라 vector도 가능하다.
for (auto/*data type*/ n : v)
{
cout << n << endl;
}
return 0;
}
동작 원리
위 예제에서 vector에 적용된 range-based for 문은 컴파일러에 의해 아래의 코드로 변환된다.
for (auto p = begin(v); p != end(v); ++p)
{
auto n = *p;
cout << n << endl;
}
즉, range-based for 문이 정상적으로 동작하려면 " : " 오른쪽에 오는 대상을 인자로 받는 begin과 end (일반)함수가 정의되어 있어야 한다. 배열, STL 컨테이너, 그리고 initializer_list에 대해서는 라이브러리에 이미 이 함수들이 정의되어 있기 때문에 바로 적용이 가능하다.
응용
사용자 정의 타입의 객체를 range-based for 문에서 사용하려면 해당 타입에 대한 begin과 end 함수를 명시적으로 구현해줘야 한다. 간단한 예제를 살펴보자.
struct Point3D
{
Point3D (int a, int b, int c) : x(a), y(b), z(c) {}
int x, y, z;
};
// begin과 end 함수를 Point3D 타입에 대해 명시적으로 구현
int* begin (Point3D& p) { return &(p.x); }
int* end (Point3D& p) { return &(p.z) + 1; } //< end()는 마지막 인자 다음 주소
Point3D 객체에 대해서도 begin과 end 함수가 존재하므로, 이제는 아래와 같이 Point3D 객체에 대해서도 range-based for 문을 적용할 수 있다.
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
Point3D p(1, 2, 3);
for (auto n : p)
{
cout << n << endl;
}
return 0;
}
'NC University > Advanced C++' 카테고리의 다른 글
5일차 - 가변인자 템플릿 (variadic template) (2) (0) | 2015.08.21 |
---|---|
5일차 - 가변인자 템플릿 (variadic template) (1) (0) | 2015.08.12 |
5일차 - begin & end (0) | 2015.08.10 |
5일차 - initializer_list (0) | 2015.08.05 |
4일차 - 객체의 field 초기화 (field initializer) (0) | 2015.08.04 |