KoreanFoodie's Study
Effective Modern C++ | 항목 13 : iterator 보다 const_iterator 를 선호하라 본문
Tutorials/C++ : Advanced
Effective Modern C++ | 항목 13 : iterator 보다 const_iterator 를 선호하라
GoldGiver 2022. 10. 26. 09:53
C++ 프로그래머의 필독서이자 바이블인, 스콧 마이어스의 Modern Effective C++ 를 읽고 기억할 내용을 요약하고 있습니다. 꼭 읽어보시길 추천드립니다!
항목 13 : iterator 보다 const_iterator 를 선호하라
핵심 :
1. iterator 보다 const_iterator 를 선호하라.
2. 최대한 일반적인 코드에서는 begin, end, rbegin 등의 비멤버 버전들을 해당 멤버 함수들보다 선호하라.
C++98 에서는, const_iterator 사용이 쉽지 않았다.
typedef std::vector<int>::iterator IterT;
typedef std::vector<int>::const_iterator ConstIterT;
std::vector<int> values;
...
ConstIterT ci =
std::find(
static_cast<ConstIterT>(values.begin()),
static_cast<ConstIterT>(values.end()),
value_to_find);
values.insert(static_cast<IterT>(ci), value_to_modify);
위에서 Iterator 에서 const_iterator 로의 캐스팅을 통해 ci 를 받아내고 있는 과정에서 다소 작위적인 왜곡이 가해지고 있다. 또한, C++98 에서는 insert / remove 시 iterator 만 사용할 수 있었기 때문에, const_iterator 에서 iterator 로의 캐스팅을 시도하고 있는데, 해당 변환은 이식성 있는 변환이 존재하지 않아 컴파일되지 않을 수 있다!
대신 C++11 에서는 다음과 같이 코드를 고쳐서 정상 작동하도록 만들 수 있다.
auto it =
std::find(values.cbegin(), values.cend(), value_to_find);
values.insert(it, value_to_modify);
위와 같은 코드가 문제가 생기는 경우는, begin 이나 end 사용 시, 멤버 함수를 사용해서 생길 수 있는 라이브러리 호환 관련 경우 말고는 찾기 힘들다. 즉, 다음과 같이 바꾸면 더 일반화된 경우를 지원할 수 있다.
template<typename C, typename V>
void findAndInsert(C& container,
const V& targetVal,
const V& insertVal)
{
using std::cbegin;
using std::cend;
auto it = std::find(cbegin(container), cend(container), targetVal);
container.insert(it, insertVal);
}
위 코드는 C++14 에서는 잘 동작하지만, C++11 에서는 비멤버 버전의 cbegin, cend, rbegin, rend, crbegin, crend 는 추가되지 않아, 아래와 같이 직접 구현해야 한다.
template<class C>
auto cbegin(const c& container)->decltype(std::begin(container))
{
return std::begin(container);
}
놀랍게도, 비멤버 cbegin 은 멤버 cbegin을 호출하지 않는다. 이렇게 구현한 이유는, begin 만 직접적으로 제공하고, cbegin 을 제공하지 않는 컨테이너에 대해서도 사용자가 만든 비멤버 cbegin 을 사용할 수 있기 때문이다.
'Tutorials > C++ : Advanced' 카테고리의 다른 글
Effective Modern C++ | 항목 15 : 가능하면 항상 constexpr 를 사용하라 (0) | 2022.10.26 |
---|---|
Effective Modern C++ | 항목 14 : 예외를 방출하지 않을 함수는 noexcept 로 선언하라 (0) | 2022.10.26 |
Effective Modern C++ | 항목 12 : 재정의 함수들을 override 로 선언하라 (0) | 2022.10.26 |
Effective Modern C++ | 항목 11 : 정의되지 않은 비공개 함수보다 삭제된 함수를 선호하라 (0) | 2022.10.26 |
Effective Modern C++ | 항목 10 : 범위 없는 enum 보다 범위 있는 enum 을 선호하라 (0) | 2022.10.26 |
Comments