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)