我的类中的C ++迭代器没有将我的结构作为一个类型

时间:2015-04-04 16:13:20

标签: c++ class vector iterator

我有一个名为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

任何想法有什么不对?我相当肯定答案很简单,但我无法弄明白。先感谢您。

1 个答案:

答案 0 :(得分:2)

那是因为您在之后声明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已经定义。

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

例如,这是我的一个自定义容器的片段: - 内部类型和结构 - 基础迭代器 - 公共typedef - 成员 - 公共界面 然后,一切都在正确的地方。

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;
};