|  | Home | Libraries | People | FAQ | More | 
      This is the constraint on the Derived
      template parameter to iterator_interface, view_interface
      and sequence_container_interface:
    
std::enable_if_t< std::is_class<Derived>::value && std::is_same<Derived, std::remove_cv_t<Derived>>::value>
      This prevents instantiating an interface template with an int,
      a const type, a reference type,
      etc.
    
      Further constraints are not possible (for instance, that view_interface is given a Derived template parameter for a type that
      has a begin()
      and end()),
      because Derived is an incomplete
      type within each *_interface
      template.
    
struct
    
      The interface templates rely mostly on public members provided by their Derived template parameter. However, iterator_interface
      requires you to supply base_reference() functions if you want it to act like an adaptor.
      Since at least the non-const overload
      provides a non-const lvalue reference
      to one of your types data members, it will break the encapsulation of many
      types to leave base_reference() a public member. To allow users to keep these
      overloads private, access exists.
    
iterator_interface
      Can Act Like an Adaptor, And the Other Interface Templates Can't
    
      There wouldn't be much point in adding this functionality to view_interface, because it only
      uses the begin()
      and end()
      of the Derived type anyway.
    
      For sequence_container_interface
      it also does not make much sense. Consider how many container adaptors you've
      written. That's a use case that does not come up often.
    
iterator_interface
      Takes a Lot of Template Parameters, And the Other Interface Templates Don't
    
      iterator_interface does in fact
      take a lot of template parameters. However, it usually only takes three: the
      Derived type, the iterator
      category, and the iterator's value_type.
    
      When you make a proxy iterator, you typically use the proxy_iterator_interface alias,
      and you again only need the same three template parameters. Though you can
      opt into more template parameters, the rest are seldom necessary.
    
      By contrast, the view_interface and sequence_container_interface
      templates have very few template parameters. For view_interface, this is because
      there are no member typedefs in the view
      concept. For sequence_container_interface,
      it was deemed ridiculous to create a template whose purpose is to reduce code
      size, which takes 14 template parameters.
    
sequence_container_interface
      Does not Deduce Nested Types Like iterator
    
      sequence_container_interface
      could deduce some of the nested types required for a standard sequence container.
      For instance, iterator can
      be deduced as decltype(*begin()).
      However, a type D derived from
      sequence_container_interface
      may need to use some of these nested types — like iterator
      — in its interface or implementation. If this is the case, those nested
      types are not available early enough in the parse to be used in D, if they come from deductions in sequence_container_interface.
      This leaves the user in the awkward position of defining the same nested type
      with a different name that can be used within D.
      It seems better to leave these types for the user to define.
    
sequence_container_interface
      Does not Support Associative or Unordered Associative Containers
    That's right. Associative containers have an interface that assumes that they are node-based containers. On modern hardware, node-based containers are not very efficient, and I don't want to encourage people to write more of them. Unordered associative containers have an interface that precludes open addressing. I don't want to encourage more of that either.
sequence_container_interface
      Does not Satisfy the Allocator-Aware Container Requirements
    
      It may not be immediately obvious, but sequence_container_interface
      simply cannot help with the allocator-aware requirements. All of the allocator-aware
      requirements but 3 are special members and constructors. A CRTP
      base template is unable to provide those, based on the language rules. That
      leaves the allocator_type typedef,
      which the user must provide; member swap(), which is already a container requirement
      (the allocator-aware table entry just specifies that member swap() must be constant-time); and get_allocator(),
      which again is something the user must provide.
    
      Most of the difficulty of dealing with allocators has to do with the implementation
      details of their use within your container. sequence_container_interface
      provides missing elements of a sequence container's interface, by calling user-provided
      members of that same interface. It cannot help you with your container's implementation.