具有唯一指针的链表被用作类型

linked list with unique pointers being used as type

我在让我的链表(它实际上是一个方形列表)通过教授给我的测试时遇到问题,我不确定我应该做什么。

这是我的代码:

/** LinkedList class declaration. */
template <typename T>
class LinkedList;

template <class TNode>
class Iterator
{
    /* Helper class to provide pointer like facilities around a node */
    friend class LinkedList<typename TNode::value_type>;
    TNode* pNode; //The node oriented with this instance of iterator.

    //Iterator(TNode* _pNode) : pNode(_pNode) {}
public:
    Iterator(TNode* _pNode) : pNode(_pNode) {}
    using value_type = typename TNode::value_type;
    //using size_type = std::size_type;
    using pointer = TNode*;
    using difference_type = std::ptrdiff_t;
    using reference = value_type&;
    using iterator = Iterator<TNode>;
    using iterator_category = std::bidirectional_iterator_tag;

    .............removed unneeded code...............       

    value_type get() {
        return pNode->_data;
    }

    typename TNode::value_type &operator*(){ return pNode->_data; }
};

template <typename T>
class Node
{
    friend class LinkedList<T>;
    friend class Iterator<Node<T> >;
    Node() : _next(0), _prev(0), _head(0), _nextHead(0), _prevHead(0) {}
    Node(T data) : _data(data), _next(0), _head(0), _nextHead(0), _prevHead(0) {}
    Node(T data, Node<T>* next, Node<T>* prev, Node<T>* head, Node<T> nextHead, Node<T> prevHead) :
        _data(data), _next(next), _prev(prev), _head(head), _nextHead(nextHead), _prevHead(prevHead){}

    T _data;
    Node<T>* _next;
    Node<T>* _prev;
    Node<T>* _head;
    Node<T>* _nextHead;
    Node<T>* _prevHead;

public:
    typedef T value_type;
};

template <typename T>
class LinkedList
{

public:
    using size_type = std::size_t;

private:
    Node<T>* first;
    Node<T>* last;
    Node<T>* lastHead;
    size_type _count = 0;
    double columnNumbers = 0;

public:

    typedef T value_type;
    using pointer = std::unique_ptr<Node<T>>;
    using iterator = Iterator<Node<T>>;
    using difference_type = std::ptrdiff_t;
    using reference = T&;
    using const_reference = T const&;
    using const_pointer = T const*;
    using const_iterator = iterator const;
    using reverse_iterator = std::reverse_iterator < iterator >;
    using const_reverse_iterator = reverse_iterator const;

    LinkedList() : first(0), last(0), lastHead(0) { }
    ~LinkedList()
    {
    .............removed unneeded code...............
    }

    iterator                begin(){ return iterator(first); }
    iterator                end(){ return iterator(last); }
    const_iterator          begin() const { return const_iterator(first); }
    const_iterator          end() const { return const_iterator(last); }
    const_iterator          cbegin() const { return const_iterator(first); }
    const_iterator          cend() const { return const_iterator(last); }
    reverse_iterator        rbegin() { return reverse_iterator(last); }
    reverse_iterator        rend() { return reverse_iterator(first); }
    const_reverse_iterator  rbegin() const { return const_reverse_iterator(last); }
    const_reverse_iterator  rend() const { return const_reverse_iterator(first); }
    const_reverse_iterator  crbegin() const { return const_reverse_iterator(last); }
    const_reverse_iterator  crend() const { return const_reverse_iterator(first); }

    .............removed unneeded code...............

    void insert(T data)
    {
    .............removed unneeded code...............
    }

    void reorder() { // this reorders the head pointers so they are all in the correct spot for the square list
    .............removed unneeded code...............
    }

    bool erase(iterator& _iNode) //True for success, vice versa
    {
    .............removed unneeded code...............
    }

    void clear()
    {
    .............removed unneeded code...............
    }
};

template <typename T>
bool operator==(Iterator<Node<T>> const& lhs, Iterator<Node<T>> const& rhs){ 
    return lhs.compare(rhs);
}

这是我应该做的测试 运行

BOOST_AUTO_TEST_CASE(ut_Rvalue_insert_scrambled_int) {
    typedef std::unique_ptr<int> UP;
    std::vector<int> data{ 9, 10, 7, 8, 5, 6, 3, 4, 1, 2 };
    LinkedList<UP> sqi;
    for (auto datum : data) {
        sqi.insert(UP(new int(datum)));
    }

    std::sort(data.begin(), data.end());
    std::vector<int> dup;
    for (auto iter = sqi.begin(); iter != sqi.end(); ++iter) {
        dup.push_back(*iter->get());
    }

    std::sort(data.begin(), data.end());
    std::sort(dup.begin(), dup.end());
    BOOST_CHECK(dup.size() == data.size());
    BOOST_CHECK_EQUAL_COLLECTIONS(dup.begin(), dup.end(), data.begin(), data.end());
}

编译时出现以下错误:

Error   1   error C2819: type 'Iterator<Node<T>>' does not have an overloaded member 'operator ->'   ut_square_list_10_insert_rvalue.cpp    33

Error   2   error C2232: '->Iterator<Node<T>>::get' : left operand has 'class' type, use '.'    ut_square_list_10_insert_rvalue.cpp 33  1

所以,我知道这是一个与指针相关的问题,但我不知道怎么做,或者我应该在这里做什么。

特别是这一行...

dup.push_back(*iter->get());

是否有更好的设置方法,或者他是否要求我重载 -> 运算符?

我试着把它改成这样(尽管我的教授不希望这样——他撕掉了当前的 ut 文件并放入了新的副本,所以他希望它以上述方式工作,而不是这样方式)

dup.push_back(*iter.get());

它不再给我重载错误,但它现在给我这个吗:

Error   1   error C2280: 'std::unique_ptr<int,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' : attempting to reference a deleted function

好的,让我们看看这里的类型。

您有 LinkedList<UP>std::vector<int>。 因此,当您尝试使用列表的迭代器将元素推送到 vector 时,您必须使用 iter.get() 从迭代器获取 UP 值,然后使用 operator *.[=16 取消引用它=]

所以最后一行应该是这样的: dup.push_back(*iter.get());

既然这个项目已经提交和标记了,我想我会给出答案的。

value_type *operator->() const {
    TNode* node = pNode;
    value_type* nodeData = &node->_data;
    return nodeData;
}

基本上,根据我的理解以及我创建链表的方式,我需要重载 -> 运算符并传递一个指向数据引用的指针。

如果有人能对此进行更多解释,我将不胜感激。很难理解为什么我需要这样做,但这是我能弄清楚如何实现这一目标的唯一方法,并且是教授接受的答案(我没有在项目上失去任何分数) .