简体   繁体   中英

How implement a custom std collection in C++?

I want to implement a custom collection data structure in std style. There is already a similar question on this site, but this guy is explicitly asking about not using any given std functionality.

The implementation should be compatible with the rest of the standard library and provide the same interface, for example iterators and type traits. Which base class should I inherit from and what does my class have to implement?

To provide information about the actual data structure, it is a hash map which values are stored continuously in memory. Internally, I will use two std::vector s and one std::unordered_map .

Which base class should I inherit from

None. Standard containers are not polymorphic; their interface requirements are informally specified in terms of expressions that must be supported. (In the future, they might be formally specified as "concepts"; but that's not part of the language yet.)

what does my class have to implement?

See the [container.requirements] section of the C++ standard (currently section 23.2 of C++11); in particular the tables specifying the operations that various container types must support. As a hash map, it should support the requirements for "unordered associative containers".

Start with an interface similar to this:

template <
    typename Key,
    typename T,
    class Hash = hash<Key>,
    class Pred = equal_to<Key>,
    class AllocH = allocator< pair<const Key,T> >,  // unordered_map allocator
    class AllocV = allocator<T> > // vector allocator
class hash_map {
public:
  typedef std::pair<Key, T> value_type;

private:
  using first_index = std::vector<T>; // C++11 typedef substitute syntax
  using second_index = std::unordered_map<Key, T>;

public:          
  using first_index_iterator = typename first_index::iterator;
  using second_index_iterator = typename second_index::iterator;      
  //defaults
  using iterator = first_index_iterator;
  using const_iterator = first_index_const_iterator;

  iterator begin();
  const_iterator begin() const;

  iterator end();
  const_iterator end() const;

  bool empty() const;

  iterator find(const Key&);
  const_iterator find(const Key&) const;

  std::pair<iterator, bool> insert(const value_type&);
  void erase(iterator);  
  void clear();    
};

You are not supposed to add your collections to the std namespace, however if you proceed nevertheless, I strongly suggest you use namespace versioning when you publish your library headers:

// hash_map.hpp
namespace std 
{
  namespace ex_v1  // my std namespace extensions v1
  {
      template <...> class hash_map { ... }    
  }

  using namespace ex_v1;
}

and further, consider the new inline versioning feature of C++11:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM