your programing

사용되지 않는 std :: iterator 준비

lovepro 2020. 12. 25. 23:35
반응형

사용되지 않는 std :: iterator 준비


3 월 21 에 표준위원회는 P0174std::iterator 에서 제안 된 폐기를 승인하기로 투표했습니다 .

void 인수의 긴 시퀀스는 단순히 typedef클래스 정의 자체에 예상되는 s를 제공하는 것보다 독자에게 훨씬 덜 명확 합니다. 이는 설정된 패턴을 따르는 현재 작업 초안에서 취한 접근 방식입니다.

상속 이전 std::iterator에는 반복기 상용구 구현에서 지루함을 제거하도록 권장되었습니다. 그러나 지원 중단에는 다음 중 하나가 필요합니다.

  1. 반복자의 보일러는 이제 모든 필요한 포함해야합니다 typedef
  2. 반복자와 함께 작동하는 알고리즘은 이제 반복기 auto에 의존하지 않고 형식을 선언 하는 대신 사용해야 합니다.
  3. Loki Astari는 다음std::iterator_traits 에서 상속하지 않고 작동하도록 업데이트 할 수 있다고 제안 했습니다.std::iterator

호환성을 염두에두고 사용자 지정 반복기를 디자인 할 때 이러한 옵션 중 어떤 옵션을 기대해야하는지 누군가 알려줄 수 있습니까 ?


논의 된 대안은 분명하지만 코드 예제가 필요하다고 생각합니다.

대체 언어가없고 부스트 또는 자체 버전의 반복기 기본 클래스에 의존하지 않는 경우 사용하는 다음 코드가 아래 코드에 std::iterator고정됩니다.

std::iterator

template<long FROM, long TO>
class Range {
public:
    // member typedefs provided through inheriting from std::iterator
    class iterator: public std::iterator<
                        std::forward_iterator_tag, // iterator_category
                        long,                      // value_type
                        long,                      // difference_type
                        const long*,               // pointer
                        const long&                // reference
                                      >{
        long num = FROM;
    public:
        iterator(long _num = 0) : num(_num) {}
        iterator& operator++() {num = TO >= FROM ? num + 1: num - 1; return *this;}
        iterator operator++(int) {iterator retval = *this; ++(*this); return retval;}
        bool operator==(iterator other) const {return num == other.num;}
        bool operator!=(iterator other) const {return !(*this == other);}
        long operator*() {return num;}
    };
    iterator begin() {return FROM;}
    iterator end() {return TO >= FROM? TO+1 : TO-1;}
};

( 원저자의 허가 가있는 http://en.cppreference.com/w/cpp/iterator/iterator의 코드 ).

없이 std::iterator

template<long FROM, long TO>
class Range {
public:
    class iterator {
        long num = FROM;
    public:
        iterator(long _num = 0) : num(_num) {}
        iterator& operator++() {num = TO >= FROM ? num + 1: num - 1; return *this;}
        iterator operator++(int) {iterator retval = *this; ++(*this); return retval;}
        bool operator==(iterator other) const {return num == other.num;}
        bool operator!=(iterator other) const {return !(*this == other);}
        long operator*() {return num;}
        // iterator traits
        using difference_type = long;
        using value_type = long;
        using pointer = const long*;
        using reference = const long&;
        using iterator_category = std::forward_iterator_tag;
    };
    iterator begin() {return FROM;}
    iterator end() {return TO >= FROM? TO+1 : TO-1;}
};

Option 3 is a strictly more-typing version of Option 1, since you have to write all the same typedefs but additionally wrap iterator_traits<X>.

Option 2 is unviable as a solution. You can deduce some types (e.g. reference is just decltype(*it)), but you cannot deduce iterator_category. You cannot differentiate between input_iterator_tag and forward_iterator_tag simply by presence of operations since you cannot reflexively check if the iterator satisfies the multipass guarantee. Additionally, you cannot really distinguish between those and output_iterator_tag if the iterator yields a mutable reference. They will have to be explicitly provided somewhere.

That leaves Option 1. Guess we should just get used to writing all the boilerplate. I, for one, welcome our new carpal-tunnel overlords.

참조 URL : https://stackoverflow.com/questions/37031805/preparation-for-stditerator-being-deprecated

반응형