2017-11-16 8 views
2

내 클래스는boost :: iterator_adaptor의 순회 범주가 적응 된 반복자의 범주에 의해 결정됩니까? <code>boost::iterator_adaptor</code>에서 상속

private: 

using is_bidirectional = std::is_convertible< 
    iterator_category, std::bidirectional_iterator_tag>; 

typename std::enable_if<is_bidirectional::value>::type 
decrement() { ... } 

과 같은 코드를 가지고 있으며, enable_if 부분이 중복 있는지 궁금하고있다. 서면에 따르면 적응 형 반복기가 양방향이 아닌 경우 decrement() 오버로드가 활성화되지 않습니다. 그러나 boost::iterator_adaptor이 이미 SFINAE을 사용하고 있는지 여부를 알지 못하므로 개인용 오버로드의 순회 범주에 대해 염려 할 필요가 없습니다. 코드가 컴파일되고 올바르게 작동합니다. 나는 enable_if par이 유용한지 또는 중복되는지 묻는 것입니다.

답변

2

예.

사실 기본적으로 어댑터는 기본 반복기의 범주를 미러링합니다.

#include <boost/iterator_adaptors.hpp> 

template <typename BaseIterator> 
struct Adapt : boost::iterator_adaptor<Adapt<BaseIterator>, BaseIterator> { 
    using base = boost::iterator_adaptor<Adapt<BaseIterator>, BaseIterator>; 
    using base::base; 
    using base::operator=; 
}; 

#include <iostream> 
#include <iterator> 
#include <typeinfo> 

template <typename It> 
std::string cat(It const&) { 
    return typeid(typename std::iterator_traits<It>::iterator_category).name(); 
} 

template <typename It, typename OutIt> 
void test(std::string caption, It f, It l, OutIt out) { 
    Adapt<It> af{f}, al{l}; 

    std::cout << caption << ", adapts to " << cat(af) << "\t"; 
    std::copy(af, al, out); 
    std::cout << "\n"; 
} 

template <typename Container, typename OutIt> 
void test(std::string caption, Container const& c, OutIt out) { 
    using BaseIterator = typename Container::const_iterator; 
    Adapt<BaseIterator> f{c.begin()}, l{c.end()}; 

    test(caption, f, l, out); 
} 

#include <vector> 
#include <forward_list> 
#include <list> 
#include <sstream> 

int main() { 
    using V = std::vector<int>; 
    using L = std::list<int>; 
    using FL = std::forward_list<int>; 
    using II = std::istream_iterator<int>; 
    using OI = std::ostream_iterator<int>; 

    static_assert(std::is_same<std::random_access_iterator_tag, std::iterator_traits<V::iterator>::iterator_category>{}, ""); 
    static_assert(std::is_same<std::bidirectional_iterator_tag, std::iterator_traits<L::iterator>::iterator_category>{}, ""); 
    static_assert(std::is_same<std::forward_iterator_tag, std::iterator_traits<FL::iterator>::iterator_category>{}, ""); 
    static_assert(std::is_same<std::input_iterator_tag, std::iterator_traits<II>::iterator_category>{}, ""); 
    static_assert(std::is_same<std::output_iterator_tag, std::iterator_traits<OI>::iterator_category>{}, ""); 

    OI out(std::cout, " "); 
    test("vector  ", V { 1,2,3 }, out); 
    test("list  ", L { 4,5,6 }, out); 
    test("forward_list", FL { 7,8,9 }, out); 
    { 
     std::istringstream iss("10 11 12"); 
     II f(iss), l; 
     test("stream input", f, l, out); 
    } 
} 

Live On Coliru

는 012,369 통해 출력을 필터링 ¹
vector  , adapts to std::random_access_iterator_tag 1 2 3 
list  , adapts to std::bidirectional_iterator_tag 4 5 6 
forward_list, adapts to std::forward_iterator_tag 7 8 9 
stream input, adapts to std::input_iterator_tag 10 11 12 

을 prints¹ 어떤 : 여기

가 작동하는 포괄적 인 테스트입니다더 예쁘기 유형 정보

+0

답변은 [귀하의 이전 질문] (https://stackoverflow.com/questions/47320372/does-boostiterator-adaptor)에 대한 답변으로 작성했기 때문에 질문 문구에 잘 연결되지 않습니다. -conform-to-iterator-category) 이제 삭제되었습니다 – sehe

+1

고마워요. 훌륭한 데모. 따라서 iterator_adaptor는 적용된 반복자 유형에 필요한 메소드 만 구현하는 것으로 보입니다. 내가 과부하()를 제공했다면 forward_iterator와 같이 작동하지 않을까 걱정했다. 테스트를 위해 forward_list를 사용하는 것이 좋습니다. 나는 그걸 생각하지 않았다. – THK