AlgebraMaster

Modern C++ 创造非凡 . 改变世界

导航

CPP2nd CRTP Facade 模式

书中源码不全,看看我这个?

#include <iostream>
#include <type_traits>
#include <vector>
#include <iterator>
template<typename Derived, typename Value, typename Category, typename Distance = std::ptrdiff_t>
struct IteratorFacade{
    using value_type = std::remove_cvref_t<Value>;
    using reference = value_type& ;
    using pointer = value_type*;
    using difference = Distance;
    using iterator_category = Category;

    reference operator*() const { return as_derived().dereference(); }

    Derived& operator++() {
        as_derived().increment();
        return as_derived();
    }

    Derived operator++(int){
        Derived ret(as_derived());
        as_derived().increment();
        return ret;
    }

    friend bool operator==(const IteratorFacade& lhs, const IteratorFacade& rhs) {
        return lhs.as_derived().equals(rhs.as_derived());
    }

    friend bool operator!=(const IteratorFacade& lhs, const IteratorFacade& rhs) {
        return !operator==(lhs, rhs);
    }




private:
    Derived& as_derived() { return *static_cast<Derived*>(this); }
    const Derived& as_derived() const { return *static_cast<const Derived*>(this); }
};


struct Person{
    std::string firstName;
    std::string lastName;
};


template<typename Iterator, typename T>
struct ProjectIterator: public IteratorFacade<ProjectIterator<Iterator, T>,
        T,
        typename std::iterator_traits<Iterator>::iterator_category,
        typename std::iterator_traits<Iterator>::difference_type>{


    using iter_value_type = typename std::iterator_traits<Iterator>::value_type;

    Iterator iter;
    T iter_value_type::* member; ;

    void increment(){
        ++iter;
    }
    void decrement () {
        --iter;
    }
    bool equals( ProjectIterator const& other) const {
        return iter == other.iter;
    }

    T &dereference(){ return  (*iter ).*member; }
    T &dereference() const { return  (*iter ).*member; }
    ProjectIterator(Iterator iter_v, T iter_value_type::* mem_v):iter(iter_v), member(mem_v) {}
};

template< typename Iterator, typename Base, typename T>
auto project( Iterator iter, T Base::* member)  {
    return ProjectIterator< Iterator,  T >(iter, member );
}

int main(){
    std::vector<Person> persons = {{"hello","world"},
                                   {"David","json"}

    };

    auto b = project( persons.begin(), &Person ::firstName );
    auto e = project(persons.end(), &Person::lastName);

    std::copy(b,e, std::ostream_iterator<std::string>(std::cout, "\n"));
}

Ref:

Cpp-Templates-2ed/11_inheritance.md at master · downdemo/Cpp-Templates-2ed (github.com)

posted on 2022-11-23 04:12  gearslogy  阅读(101)  评论(0编辑  收藏  举报