2016-11-21 8 views
3

cplusplus.com에서이 조각에, 예를 들어, 참조 :다른 템플릿 유형 인수를 사용하는 대신 iterator_traits를 템플릿 함수에서 사용하는 이유는 무엇입니까?

template <class InputIterator, class T> 
typename iterator_traits<InputIterator>::difference_type 
count(InputIterator first, InputIterator last, const T& val) 
{ 
    typename iterator_traits<InputIterator>::difference_type ret = 0; 
    while (first!=last) { 
     if (*first == val) 
      ++ret; 
     ++first; 
    } 
    return ret; 
} 

질문은 왜 오히려 다른 템플릿 인수에 복용보다 이러한 맥락에서 iterator_traits을 사용되어 다음과 같이 :

template <class InputIterator, class T, class DiffType> 
DiffType count(InputIterator first, InputIterator last, const T& val) 
{ 
    DiffType ret = 0; 
    while (first!=last) { 
     if (*first == val) 
      ++ret; 
     ++first; 
    } 
    return ret; 
} 
+3

꽤 넓 습니다만 반복기 특성과 일반적으로 구성원 유형과 같은 일반적인 특성은 적절한 규칙을 사용하여 잘 작동합니다. 규칙에 따라 "표준"특성을 사용하면 알고리즘과 데이터 구조가 표준 템플릿 라이브러리의 나머지 부분과 잘 연동되어보다 나은 메타 프로그래밍이 가능합니다. – AndyG

+0

또 다른 템플릿 클래스 *를 정의 할 수는 있지만 한번만하면 다른 모든 알고리즘에 대해 다시 수행하고 싶지 않습니다. –

+0

밀도가 높지만 생각하고있는 것을 보여줄 수 있습니까? 마지막 문장에서? – Quentin

답변

4

제안 당신 주석에 제안 된 - 다른 템플릿 인수를 취하는 기능 -은 의도 한대로 작동하지 않습니다.

template <class InputIterator, class T, typename DiffType> 
DiffType count(InputIterator first, InputIterator last, const T& val) 
{ 
    DiffType ret = 0; 
    while (first!=last) { 
     if (*first == val) 
      ++ret; 
     ++first; 
    } 
    return ret; 
} 

이 코드의 문제점이 더 이상 컴파일 없다는 것이다 : 여기에 제시 한 코드는

std::vector<int> v = /* ... */; 
auto numElems = count(v.begin(), v.end(), 137); // <--- Error! 

여기서 문제는 그 함수 템플릿을 호출하기 위해, 모든 템플릿 인수 인수 형에서 유추 할 수 있거나 호출자가 명시 적으로 지정해야합니다. 여기서 유형 DiffType은 인수 유형에서 추론 할 수 없습니다 (InputIteratorT 유형은 두 개의 인수에서 유추 할 수 있지만 서명 자체만으로는 문맥이 없음). 따라서이 호출은 컴파일러 오류로 인해 실패합니다. std::iterator_traits의 사용은 이터레이터 유형 자체에서 반복자에 대한 정보를 추출하기위한 일반적인 템플릿 패턴입니다.

+0

글쎄, DiffType은 적어도 첫 번째 템플릿 인수 일 수 있습니다. 아직 모든 것이 공감할 수는 없지만, 조금 더 나은 ... – Deduplicator

+0

@BoPersson 오, 좋은 지적. 내가 수정 한 내용이 수정 된 것 같아? – templatetypedef

+0

@Deduplicator 그래도 명시 적으로 차이 유형을 제공 할 필요가 없습니까? – templatetypedef