2014-11-30 5 views
0

반복자가 가리키는 2 개의 값을 교환하고 싶습니다. 그래서 반복자를 가져 오는 템플릿 함수를 전문화하고 싶습니다. 내가 어떻게 할 수 있니? 비 반복자에 대한반복자에 대한 C++ 템플릿 전문화

기능 : 반복자에 대한

template <typename T> 
void exch(T &a, T &b) 
{ 
    T c(std::move(a)); 
    a = std::move(b); 
    b = std::move(c); 
} 

기능 : 물론

template <typename It> 
void exch(It &a, It &b) 
{ 
    auto c(std::move(*a)); 
    *a = std::move(*b); 
    *b = std::move(c); 
} 

, 나는 오류 얻을이 개 기능 :

/프로젝트/DFSTL를/주 .cpp : 17 : 6 : 오류 : 'template void exch (It &, It &)'의 재정의 '

+2

SFINAE 또는 is_iterator 특성에 태그를 디스패치합니다. 구현은 쉽게 찾을 수 있습니다. 하지만 정말로 이것을하고 싶습니까? 만약 누군가가 정말로 반복자를 교환하고 싶다면? –

+7

'std :: iter_swap()'을 사용할 수 있습니다. – 0x499602D2

답변

2

-ab를 교환하고 ab에 의해 간접적으로 언급 된 것들을 교환은, 과부하하는 유혹 것입니다. 그러나 그렇게하면 정말 이상한 행동을하게됩니다.

첫 번째 단계에서는 자신의 is_iterator 특성 클래스를 작성해야합니다. 이것은 다양한 방법을 통해 수행 할 수 있습니다. 일부 컴파일러에서 작동하는 기능은 SFINAE 해상도 인 std::iterator_traits<It>::iterator_category을 사용하고 input_iterator_tag 또는 output_iterator_tag이 해당 유형의 기반인지 확인하는 것입니다.

보통 void* 및 cv 변종을 감지해야합니다. 비 반복자에서 std::iterator_traits이 구현 정의 결과를 생성하므로 여전히 구현 정의 동작입니다.

더 복잡한 방법은 반복자의 유형 공리를 검사하고 테스트하는 것입니다. 모든 패스가 반복자라고 말하면됩니다. 반복자에 대한

template <class T, class=std::enable_if_t< !is_iterator<std::decay_t<T>>{} >> 
void exch(T &a, T &b) { 
    using std::swap; 
    swap(a,b); 
} 

기능 : 내가 std:: 조회하기보다는 함께 ADL 지원 맥락에서 swapiter_swap라고

template <class It, class=std::enable_if_t< is_iterator<std::decay_t<It>>{} >> 
void exch(It a, It b) { 
    using std::iter_swap; 
    iter_swap(a,b); 
} 

참고하면 is_iterator<T>가 있으면

, 당신은 SFINAE을 사용할 수 있습니다 수동으로 구현합니다. 이렇게하면 자신의 고유 네임 스페이스에 자신의 swap을 전문으로하는 유형이 자동으로 최적의 솔루션을 얻을 수 있습니다.

2

이러한 템플릿 함수는 모두 컴파일러와 동일하게 나타납니다. 그래서 컴파일러 오류가 발생합니다.

이 기능을 사용해 보셨습니까? std::swap()?

스왑이 의미있는 모든 STL 컨테이너 유형에 특화되어 있습니다. 나는이 일에 대해 조언을 할

+0

그래, 나도 알아) =하지만 나는 그들 자신을 배우고 템플릿에있는 전문가가되기 위해 내 자신의 병렬 STL 구현을 작성하려고 노력하고있다. ^) –