具有唯一指针的链表被用作类型
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;
}
基本上,根据我的理解以及我创建链表的方式,我需要重载 -> 运算符并传递一个指向数据引用的指针。
如果有人能对此进行更多解释,我将不胜感激。很难理解为什么我需要这样做,但这是我能弄清楚如何实现这一目标的唯一方法,并且是教授接受的答案(我没有在项目上失去任何分数) .
我在让我的链表(它实际上是一个方形列表)通过教授给我的测试时遇到问题,我不确定我应该做什么。
这是我的代码:
/** 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;
}
基本上,根据我的理解以及我创建链表的方式,我需要重载 -> 运算符并传递一个指向数据引用的指针。
如果有人能对此进行更多解释,我将不胜感激。很难理解为什么我需要这样做,但这是我能弄清楚如何实现这一目标的唯一方法,并且是教授接受的答案(我没有在项目上失去任何分数) .