std::count
Q.
template <class In, class T>
typename iterator_traits<In>::difference_type count(In first, In last, const T& val);
template <class In, class Pred>
typename iterator_traits<In>::difference_type count_if(In first, In last, Pred p);
위의 함수는 algorithm에 정의되어 있는 count와 count_if 알고리즘입니다.
주어진 iterator 사이에서 정해진 값이나 조건에 맞는 element의 갯수를 리턴하는 함수인데 어째서 return type으로 difference_type 이 사용되었을까요?
A.
간단히 생각해서 count 알고리즘을 구현한다면 아마 다음과 같은 코드가 될 것입니다.
template <class In, class T> int count(In first, In last, const T& val) {
int res = 0;
while (first != last) if (*first++ == val) ++res;
return res;
}
그러나 생각처럼 int가 count의 return type으로 항상 적당한 것은 아닙니다. 예를 들어 int의 범위가 작은 (8bit 혹은 16bit) 머신에서는 int가 처리할 수 있는 크기보다 더 많은 element 들이 들어 있을 수 있습니다.
또한 특정 머신에서는 성능을 위해 한 container의 element의 갯수를 적당한 범위로 제한할 수도 있을것입니다.
하지만 어떠한 경우라도 조건에 맞는 element의 갯수는 iterator_traits<In>::difference_type 의 범위보다는 작다는 것을 알 수 있습니다. 따라서 표준에서는 count와 count_if의 return type을 int나 ptrdiff_t 대신 iterator_traits<In>::difference_type 으로 정의하였습니다.
참고로 iterator_traits 의 정의와 T* 에 대한 specialization은 다음과 같습니다.
template <class Iter> struct iterator_traits {
typedef typename Iter::iterator_category iterator_category;
typedef typename Iter::value_type value_type;
typedef typename Iter::difference_type difference_type;
typedef typename Iter::pointer pointer;
typedef typename Iter::reference_type reference_type;
};
template <class T> struct iterator_traits<T*> {
typedef typename ramdom_access_iterator_tag iterator_category;
typedef typename T value_type;
typedef typename ptrdiff_t difference_type;
typedef typename T* pointer;
typedef typename T& reference_type;
};
- Bjarne Stroustrup, The C++ Programming Language - Special edition, pp526, pp552-553, Addison Wesley, 1997.
|