类中的C++迭代程序没有将结构作为类型

C++ Iterator in my class not taking in my struct as a type

本文关键字:结构 类型 C++ 迭代 程序      更新时间:2023-10-16

我有一个名为MyHashMap的类,我想实现一个迭代器,但由于某些原因我无法实现。我有一个向量,它将私有结构作为一种类型,这很好,但当我试图在公共部门中用迭代器定义它时,它表示没有声明HashEntry。这是我的课。

template<typename KeyType, typename ObjectType>
class MyHashMap 
{
  public:
/***********ITERATOR FUNCTIONS****************/
    typedef typename std::vector<HashEntry>::iterator iterator;
    typedef typename std::vector<HashEntry>::const_iterator const_iterator;
    iterator begin() { return array.begin(); }
    const_iterator begin() const { return array.begin(); }
    iterator end() { return array.end(); }
    const_iterator end() const { return array.end(); }
  private:
    struct HashEntry
    {
        KeyType     element;
        ObjectType  mapped;
        EntryType   info;
        HashEntry(  const KeyType & e = KeyType{ }, 
                    const ObjectType & m = ObjectType{ }, 
                    EntryType i = EMPTY )
                    : element{ e }, mapped{ m }, info{ i } { }
        HashEntry(  KeyType && e, 
                    ObjectType && m, 
                    EntryType i = EMPTY )
                    : element{ std::move( e ) }, mapped{ std::move( m ) }, info{ i } { }
    };
    vector<HashEntry> array;
};

我收到这些错误

error: ‘HashEntry’ was not declared in this scope
    typedef typename std::vector<HashEntry>::iterator iterator;
                             ^
error: template argument 1 is invalid
    typedef typename std::vector<HashEntry>::iterator iterator;
                                      ^
error: template argument 2 is invalid
error: ‘HashEntry’ was not declared in this scope
     typedef typename std::vector<HashEntry>::const_iterator const_iterator;
                              ^
error: template argument 1 is invalid
     typedef typename std::vector<HashEntry>::const_iterator const_iterator;
                                       ^
error: template argument 2 is invalid

有什么想法吗?我确信答案很简单,但我就是想不通。提前谢谢。

这是因为您在将HashEntry用作模板参数后声明了它。

应该是这样的:

template<typename KeyType, typename ObjectType>
class MyHashMap 
{
  private:
    struct HashEntry
    {
        KeyType     element;
        ObjectType  mapped;
        EntryType   info;
        HashEntry(  const KeyType & e = KeyType{ }, 
                    const ObjectType & m = ObjectType{ }, 
                    EntryType i = EMPTY )
                    : element{ e }, mapped{ m }, info{ i } { }
        HashEntry(  KeyType && e, 
                    ObjectType && m, 
                    EntryType i = EMPTY )
                    : element{ std::move( e ) }, mapped{ std::move( m ) }, info{ i } { }
    };
    vector<HashEntry> array;
  public:
    /***********ITERATOR FUNCTIONS****************/
    //Now you can use 'HashEntry' as it is visible now:
    typedef typename std::vector<HashEntry>::iterator iterator;
    typedef typename std::vector<HashEntry>::const_iterator const_iterator;
    iterator begin() { return array.begin(); }
    const_iterator begin() const { return array.begin(); }
    iterator end() { return array.end(); }
    const_iterator end() const { return array.end(); }
};

编辑

我认为前向声明在这里应该足够了,因为当MyHashMap被实例化时,HashEntry已经被定义了。

但我认为,您应该坚持在类(尤其是模板类)中声明事物的一个一致顺序。我总是这样做:

例如,这是我的一个自定义容器中的一个片段:-内部类型和结构-基本迭代器-公共typedefs-成员-公共接口然后,一切总是在正确的地方。

template <class T>
class SortedArray
{
protected:
    class Block
    {
      //...
    };
    class InternalCompare
    {
      //...
    };
    template <IteratorType Iter_type>
    class IteratorBase
    {
      //...
    };
    template <IteratorType Iter_type>
    class InternalIterator : public IteratorBase<Iter_type>
    {
      //...
    };
    template <IteratorType Iter_type>
    class InternalReverseIterator : public IteratorBase<Iter_type>
    {
      //...
    };
public:
    typedef SortedArray<T> MyType;
    typedef InternalIterator<IteratorType::Non_Const>           Iterator;
    typedef InternalIterator<IteratorType::Const>               ConstIterator;
    typedef InternalReverseIterator<IteratorType::Non_Const>    ReverseIterator;
    typedef InternalReverseIterator<IteratorType::Const>        ConstReverseIterator;

protected:
    DynamicBuffer<Block>    _blocks;
    Size_t                  _blocks_num;
    Size_t                  _elements_num;
    Block*                  _first_block;
    Block*                  _last_block;
public:
    SortedArray()
    {
      //...
    };
    //etc.
};

但这只是一个例子。

编辑2

对于已发布的解决方案,另一种解决方案是仅转发声明HashEntry。这只会用一行额外的代码修改您的原始代码:

//This is your original code.
template<typename KeyType, typename ObjectType>
class MyHashMap 
{
private:
    struct HashEntry; //This forward declaration is sufficient for everything to work properly.
public:
    /***********ITERATOR FUNCTIONS****************/
    typedef typename std::vector<HashEntry>::iterator iterator;
    typedef typename std::vector<HashEntry>::const_iterator const_iterator;
    iterator begin() { return array.begin(); }
    const_iterator begin() const { return array.begin(); }
    iterator end() { return array.end(); }
    const_iterator end() const { return array.end(); }
private:
    struct HashEntry
    {
        KeyType     element;
        ObjectType  mapped;
        EntryType   info;
        HashEntry(  const KeyType & e = KeyType{ }, 
                    const ObjectType & m = ObjectType{ }, 
                    EntryType i = EMPTY )
                    : element{ e }, mapped{ m }, info{ i } { }
        HashEntry(  KeyType && e, 
                    ObjectType && m, 
                    EntryType i = EMPTY )
                    : element{ std::move( e ) }, mapped{ std::move( m ) }, info{ i } { }
    };
    vector<HashEntry> array;
};