더북(TheBook)

앞에서 string 객체의 표준 비교를 사용한 결과와 상당히 다른 결과가 되었다. 이니셜이 같은 이름들은 길이를 기준으로 내림차순으로 표시된다. 물론, my_greater 조건자를 재사용할 필요가 없다면 람다 표현식을 사용해도 같은 결과를 얻을 수 있다. 람다 표현식을 사용하면 다음과 같이 작성할 수 있다.

names.sort([](const std::string s1, const std::string s2)
                { if (s1[0] == s2[0])
                  return s1.length() > s2.length();
                else
                  return s1 > s2;
                });

앞 문장과 결과는 정확히 같다.

리스트의 merge() 함수 멤버는 다른 리스트 컨테이너를 인수로 받는다. 두 컨테이너의 원소들은 오름차순으로 정렬되어 있어야 한다. 인수 리스트의 원소들은 현재 리스트의 원소들과 병합된다.

std::list<int> my_values {2, 4, 6, 14};
std::list<int> your_values{ -2, 1, 7, 10};
my_values.merge(your_values);         // my_values: -2 1 2 4 6 7 10 14
your_values.empty();                  // true를 반환

your_values의 원소들은 values로 복제가 아니라 전송되었다. 따라서 병합(merge) 연산 이후에는 your_values에 원소가 하나도 남지 않는다. 원소들의 전송은 리스트에 있는 각 노드의 포인터를 변경하는 방식으로 처리한다. 즉, 현재 컨테이너의 원소에 인수로 전달된 리스트의 원소들을 적절한 위치로 연결한다. 리스트의 노드들은 메모리에 있는 그대로 유지하고 노드들을 연결하는 포인터만 변경된다. 두 컨테이너의 원소들은 병합 과정에서 operator<()를 사용해서 비교된다. merge() 함수의 오버로드 버전은 두 번째 매개변수에 병합 연산에 사용될 비교 함수를 지정할 수 있다. 예제로 살펴보자.

std::list<std::string> my_words {“three”, “six”, “eight”};
std::list<std::string> your_words {“seven”, “four”, “nine”};
auto comp_str = [](const std::string s1, const std::string s2){ return s1[0]<s2[0]; };
my_words.sort(comp_str);                 // “eight” “six” “three”
your_words.sort(comp_str);               // “four” “nine” “seven”
my_words.merge(your_words, comp_str);    // “eight” “four” “nine” “six” “seven” “three”
 

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.