-
항목13. iterator보다 const_iterator를 선호하라Effective Modern C++ 2022. 7. 27. 16:55
const_iterator는 const를 가리키는 포인터의 STL 버전이다. const_iterator는 수정하면 안되는 값(포인터)들을 가리킨다. 반복자가 가리키는 것을 수정할 필요가 없을 때에는 항상 const_iterator를 사용하는 것이 바람직하다.
C++98에서는 iterator로 부터 const_iterator를 얻기는 쉽지 않았다. static_cast(vetor.begin()) 같이 캐스팅을 이용해 정적 캐스팅한다. 다소 작위적인 왜곡이 있다. 그뒤 삽입(삭제) 위치를 지정하려면 이걸 다시 iterator로 캐스팅해야한다. 이 과정에서 오류가 나올 수 있다. 그래서 c++98에선 사용하기 까다로웠다.
하지만 c++11에서는 모든 것이 달라졌다. 컨테이너 멤버 함수 cbeing과 cend는 const_iterator를 돌려준다. insert와 erase 같은 STL 멤버 함수들은 실제로 const_iterator를 사용한다.
템플릿 라이브러리 코드를 작성할 때 비멤버 함수로서 제공해야 하는 컨테이너들과 컨테이너 비슷한 자료구조들이 존재할 수 있다. (물론 필요 없는 함수도 존재함)그럴 때 다음과 같이 하나의 템플릿으로 일반화할 수 있다.template <typename C, typename V> void findAndInsert(C& container, const V& targetVal, const V& inserVal) { using std::cbegin; using std::cend; auto it = std::find(cbegin(container), // 비멤버 cbegin cend(contatiner), // 비멤버 cend targetVal); container.insert(it,inserVal); }C++11에서 비멤버 cbegin을 제공하지 않는다면, 직접 구현하면 된다.
templat <class C> auto cbegin(const C& container) -> decltype(std::begin(container)) { return std::begin(container); }또한 최대한 일반성을 추구한다면 비멤버 함수를 적극 사용하면 좋다.
'Effective Modern C++' 카테고리의 다른 글
항목15. 가능하면 항상 constexpr을 사용하라 (0) 2022.07.28 항목14. 예외를 방출하지 않을 함수는 noexcept로 선언하라 (0) 2022.07.27 항목12. 재정의 함수들을 override로 선언하라 (0) 2022.07.26 항목11. 정의되지 않은 비공개 함수보다 삭제된 함수를 선호하라 (0) 2022.07.25 항목10. 범위 있는 enum을 선호하라. (0) 2022.07.23