C++의 많은 내장 STL 함수들은 원하는 값이 저장된 메모리 주소(포인터)를 반환합니다. 하지만 이 주소는 컨테이너 내부의 실제 인덱스와는 직접적인 관련이 없습니다.
대표적인 예로 최댓값 요소를 찾는 std::max_element() 함수가 있습니다. 이 함수는 해당 요소의 인덱스가 아니라 메모리상의 주소를 반환하죠. 그런데 실무에서는 이 주소로부터 인덱스를 얻어야 하는 경우가 종종 발생합니다. 이번 글에서는 STL 함수가 반환한 포인터에서 인덱스를 계산하는 두 가지 방법을 살펴보겠습니다.
1. begin() 반복자를 빼서 인덱스 계산하기
컨테이너의 begin() 메서드를 호출하면 첫 번째 요소의 주소를 얻을 수 있습니다. 반환된 주소에서 이 시작 주소를 빼면 두 주소 간의 거리, 즉 인덱스를 구할 수 있습니다.
예제 코드
#include <bits/stdc++.h>
using namespace std;
int main(){
vector<int> vec = { 10, 40, 50, 60, 30 };
cout << "Max element is : " << (*max_element(vec.begin(), vec.end())) << endl;
cout << "The index of maximum element : ";
cout << max_element(vec.begin(), vec.end()) - vec.begin();
}실행 결과
Max element is : 60 The index of maximum element : 3
max_element(vec.begin(), vec.end())가 반환한 반복자에서 vec.begin()을 빼면, 최댓값이 위치한 인덱스인 3이 출력됩니다.
2. std::distance() 함수 활용하기
인덱스를 구하는 또 다른 방법은 std::distance() 함수를 사용하는 것입니다. 이 함수는 두 반복자 사이의 거리를 계산해 주며, 가독성 측면에서 더 명확하다는 장점이 있습니다.
예제 코드
#include <bits/stdc++.h>
using namespace std;
int main(){
vector<int> vec = { 10, 40, 50, 60, 30 };
cout << "Max element is : " << (*max_element(vec.begin(), vec.end())) << endl;
cout << "The index of maximum element : ";
cout << distance(vec.begin(), max_element(vec.begin(), vec.end()));
}실행 결과
Max element is : 60 The index of maximum element : 3
정리
STL 알고리즘 함수는 대부분 값 자체가 아닌 반복자(주소)를 반환하므로, 인덱스가 필요하다면 다음 두 방법 중 하나를 사용하면 됩니다.
- 반복자 차감:
반환된_반복자 - 컨테이너.begin() - std::distance():
distance(컨테이너.begin(), 반환된_반복자)
두 방법 모두 임의 접근 반복자(random access iterator)를 지원하는 vector, array 등에서 O(1) 시간에 동작하므로 성능 걱정 없이 사용할 수 있습니다.