2013-10-11 2 views
9

<algorithm> 헤더는 std::equal_range()뿐만 아니라 구성원 기능으로 일부 컨테이너를 제공합니다. 이 함수를 사용하면 귀찮은 일은 반복자 쌍을 반환하여 시작 반복자에서 끝 반복자로 반복하는 것이 지루한 일입니다. std::begin()std::end()을 사용하여 C++ 11 범위 기반 루프를 사용할 수 있기를 바랍니다.equal_range()의 반환 값에 대해 std :: begin 및 std :: end를 전문화 할 수 있습니까?

지금, 나는이 std::begin()std::end()를 전문에 관해서 모순 된 정보를 들었습니다 - 나는 들었다 그 나는 또한 당신이 당신의 자신의 전문을 제공 할 수있는 말 한 반면, 정의되지 않은 동작의 표준 네임 스페이스 결과에 아무것도 추가 std::begin()std::end()입니다.

namespace std 
{ 
    template<typename Iter, typename = typename iterator_traits<Iter>::iterator_category> 
    Iter begin(pair<Iter, Iter> const &p) 
    { 
     return p.first; 
    } 
    template<typename Iter, typename = typename iterator_traits<Iter>::iterator_category> 
    Iter end(pair<Iter, Iter> const &p) 
    { 
     return p.second; 
    } 
} 

을 그리고이 작업을 수행합니다 :

이것은 내가 지금 무슨 일을하고있다 http://ideone.com/wHVfkh

하지만,이 일의 단점은 무엇입니까 궁금? 이 작업을 수행하는 더 좋은 방법이 있습니까? 이 달리 명시하지 않는 한 네임 스페이스 stdstd을 네임 스페이스 또는 네임 스페이스 에하는 선언 또는 정의를 추가하는 경우

답변

7

17.6.4.2.1/1는 C++ 프로그램의 동작은 보증되지 않습니다. 프로그램이 표준 라이브러리 템플릿의 템플릿 전문화를 네임 스페이스 std에 추가 할 수 있습니다. 선언이 사용자 정의 유형에 따라 다르며 전문화 과정이 원본 템플릿의 표준 라이브러리 요구 사항을 충족하며 명시 적으로 금지되지 않은 경우에만 해당 프로그램에 추가 할 수 있습니다.

그렇습니다. 기술적으로 코드는 정의되지 않은 동작을 나타냅니다. 아마도 생성자에서 반복자 쌍을 취하고 begin()end() 메쏘드를 구현하는 간단한 클래스를 작성할 수 있습니다. 그러면 다음과 같이 쓸 수 있습니다.

for (const auto& elem: as_range(equal_range(...))) {} 
+0

사용자 정의 유형이 포함될 경우 'picky'가 허용되는 부분과 정확히 어떻게 다른가요? 이 쌍에는 unique_ptrs의 컨테이너를 반복하여 사용자 정의 유형으로 반복하는 반복자가 포함되어 있습니다. –

+0

작성한대로 사용자 정의에는 사용자 정의 유형이 언급되어 있지 않습니다. 이러한 템플릿은 결국 사용자 정의 형식으로 인스턴스화 될 수 있지만 관련이 없습니다. –

+1

어쨌든 "사용자 정의 형식에 의존합니다"이스케이프 해치는 템플릿 전문화에만 적용됩니다. 당신은 그렇지 않습니다. 그것들은 기본 함수 템플릿이며, 같은 이름을 가진 다른 함수 템플릿에 과부하가 발생합니다. –

관련 문제