|

C++/C Language - std::count

|
Home | Tips | Reference

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;
};

  1. Bjarne Stroustrup, The C++ Programming Language - Special edition, pp526, pp552-553, Addison Wesley, 1997.

2002.11.25. 잘못된 부분에 대해서는 에게 메일 부탁드립니다.