简体   繁体   English

如何在C ++中实现自定义std集合?

[英]How implement a custom std collection in C++?

I want to implement a custom collection data structure in std style. 我想以std风格实现自定义集合数据结构。 There is already a similar question on this site, but this guy is explicitly asking about not using any given std functionality. 在这个网站上已经有类似的问题 ,但是这个人明确地询问不使用任何给定的std功能。

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 . 在内部,我将使用两个std::vector和一个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); 请参阅C ++标准的[container.requirements]部分(目前是C ++ 11的第23.2节); 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: 您不应该将集合添加到std命名空间,但是如果继续,我强烈建议您在发布库头时使用命名空间版本控制:

// 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: 进一步,考虑C ++ 11的新内联版本控制功能:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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