반응형

한 번 포스팅으로 정리해야겠다 생각이 들어서 정리해봤다.


1. 전통적인 for

for (int i = 0; i < 10; i++)
{
std::cout << i << std::endl;
}

우리가 C++에서 반복문을 얘기할 때 가장 흔하게 사용하는 for문이다. for문 내에서 사용하는 정수를 선언하고, 이 정수를 키우거나 줄이는 등 값을 바꾸며 반복하는 방법이다.

2. C++11부터 추가된 for

for(int i : {0, 1, 2, 3, 4, 5})
{
    std::cout << i << std::endl;
}

std::vector<std::string> name_vector;
for(const auto& element : name_vector)
{
    std::cout << element << std::endl;
}

Range-based for loop라고 부른다.

변수 선언과 조작 대신 내부적으로 반복자(iterator)를 이용하여 vector와 같은 컨테이너 전체의 원소에 대해 반복을 수행한다.

쓰다보면 기존 for문에 있던 인덱스값(i)이 안 보여 귀찮게 느껴질 수도 있는데, while문 쓸 때처럼 반복문 밖에 변수를 선언하고 가져다 쓰면 된다.

깔끔해 보이는게 가장 큰 장점. 성능이 더 좋고 그런 건 없다.


3. std::for_each(<algorithm>)

std::vector<std::string> name_vector{ "test1", "test2", "test3" };
std::for_each(name_vector.begin(), name_vector.end(), [](auto& input) {std::cout << input << std::endl; });

void print(std::string& input)
{
    std::cout << input << std::endl;
}
std::vector<std::string> name_vector{ "test1", "test2", "test3" };
std::for_each(name_vector.begin(), name_vector.end(), print);

for_each는 <algorithm> 헤더에 정의되어 있는 함수다. 그래서 std::for_each의 형태로 써야 한다.

반복자의 시작과 끝, 그리고 함수를 파라미터로 받는다. 마지막 파라미터는 람다 표현식으로도 나타낼 수 있다.


4. std::transform(<algorithm>)

std::string change(std::string& input)
{
    return std::string("Changed!");
}
std::vector<std::string> name_vector{ "test1", "test2", "test3" };
std::vector<std::string> result{ "result1", "result2", "result3" };

std::transform(name_vector.begin(), name_vector.end(), result.begin(), change);
//result = {"Changed!", "Changed!", "Changed!"}

transform도 반복자를 이용한 반복문이긴 한데, 결과를 다른 컨테이너에 저장하는 역할을 한다. 물론 원본 컨테이너에 바로 저장할 수도 있다. transform도 for_each와 마찬가지로 함수 부분을 람다 표현식으로 나타낼 수 있다.


같은 구현도 다른 함수를 이용해서 서로 다르게 구현할 수 있으니 필요에 따라 적절하게 반복문을 선택해서 만들면 될 것 같다.


덤. std::for_each_n(<algorithm>,C++17)
검색하다보니 C++17에서는 for_each_n이라는 것이 추가되는 모양이다. for_each에서 반복자의 끝 대신 반복자의 시작부터 n번 반복하도록 정수를 넣는 형태인 것 같다.




참고


반응형

+ Recent posts