Перегрузка оператора << для двусвязного списка
Пытаюсь перегрузить оператор << для двусвязного списка через дружественную функцию, результат:
Ошибка C2280 "std::basic_ostream<char,std::char_traits>::basic_ostream(const std::basic_ostream<char,std::char_traits> &)": предпринята попытка ссылки на удаленную функцию DoubleLinkedList"
template<typename T>
std::ostream& operator<<(std::ostream& os, DoubleLinkedList<T>& list)
{
for (int i = 0; i < list.size_; i++)
{
os<< '[' << list[i] << "] ";
}
}
Полный код
#include <iostream>
#include <string>
template<typename T>
class DoubleLinkedList
{
public:
DoubleLinkedList();
DoubleLinkedList(const DoubleLinkedList<T>& src);
DoubleLinkedList(DoubleLinkedList<T>&& other) noexcept;
T& operator[](const int index);
bool operator==(const DoubleLinkedList<T>& right);
friend std::ostream& operator<<(std::ostream os, DoubleLinkedList<T>& list);
void insertHead(T data);
void insertTail(T data);
bool deleteHead();
bool deleteTail();
bool deleteItem(const T data);
bool searchItem(T data);
bool replaceItem(T itemOld, T itemNew);
void add(DoubleLinkedList<T>& src);
void outAll();
void clear();
~DoubleLinkedList();
private:
template<typename T>
class Node
{
public:
Node* pNext_;
Node* pPrev_;
T data_;
Node(T data = T(), Node* pNext = nullptr, Node* pPrev = nullptr)
{
this->data_ = data;
this->pNext_ = pNext;
this->pPrev_ = pPrev;
}
};
Node<T>* head_;
Node<T>* tail_;
int size_;
void swap(DoubleLinkedList<T>& other) noexcept;
Node<T>* head() { return head_; }
Node<T>* tail() { return tail_; }
void insertHead(Node<T>* x);
void insertTail(Node<T>* x);
void deleteNode(Node<T>* x);
Node<T>* searchNode(T data);
Node<T>* replaceNode(Node<T>* x, T data);
};
template<typename T>
DoubleLinkedList<T>::DoubleLinkedList()
{
head_ = tail_ = nullptr;
size_ = 0;
}
template<typename T>
DoubleLinkedList<T>::DoubleLinkedList(const DoubleLinkedList<T>& src)
{
this->clear();
Node<T>* temp = src.head_;
for (int i = 0; i < src.size_; i++)
{
insertTail(temp->data_);
temp = temp->pNext_;
}
}
template<typename T>
DoubleLinkedList<T>::DoubleLinkedList(DoubleLinkedList<T>&& other) noexcept
{
this->head_ = other.head_;
this->tail_ = other.tail_;
this->size_ = other.size_;
other.head_ = other.tail_ = nullptr;
other.size_ = 0;
}
template<typename T>
T& DoubleLinkedList<T>::operator[](const int index)
{
int counter = 0;
Node<T>* current = head_;
while (current != nullptr)
{
if (counter == index)
{
return current->data_;
}
current = current->pNext_;
counter++;
}
}
template<typename T>
bool DoubleLinkedList<T>::operator==(const DoubleLinkedList<T>& right)
{
if (size_ != right.size_)
{
return 0;
}
else
{
Node<T>* currentLeft = head_;
Node<T>* currentRight = right.head_;
while (currentLeft != nullptr)
{
if (currentLeft->data_ != currentRight->data_)
{
return 0;
}
else
{
currentLeft = currentLeft->pNext_;
currentRight = currentRight->pNext_;
}
}
return 1;
}
}
template<typename T>
void DoubleLinkedList<T>::insertHead(T data)
{
insertHead(new Node<T>(data));
}
template<typename T>
void DoubleLinkedList<T>::insertTail(T data)
{
insertTail(new Node<T>(data));
}
template<typename T>
bool DoubleLinkedList<T>::deleteHead()
{
if (head_ == nullptr)
{
return 0;
}
Node<T>* toDelete = head_;
head_ = head_->pNext_;
delete toDelete;
size_--;
return 1;
}
template<typename T>
bool DoubleLinkedList<T>::deleteTail()
{
if (tail_ == nullptr)
{
return 0;
}
Node<T>* toDelete = tail_;
tail_ = tail_->pPrev_;
delete toDelete;
size_--;
return 1;
}
template<typename T>
bool DoubleLinkedList<T>::deleteItem(const T data)
{
try
{
return (deleteNode(searchNode(data)) != nullptr);
}
catch (const char* ex)
{
std::cout << ex << std::endl;
return 0;
}
}
template<typename T>
bool DoubleLinkedList<T>::searchItem(T data)
{
return (searchNode(data) != nullptr);
}
template<typename T>
bool DoubleLinkedList<T>::replaceItem(T itemOld, T itemNew)
{
try
{
return (replaceNode(searchNode(itemOld), itemNew) != nullptr);
}
catch (const char* ex)
{
std::cout << ex << std::endl;
return 0;
}
}
template<typename T>
void DoubleLinkedList<T>::add(DoubleLinkedList<T>& src)
{
Node<T>* toAdd;
while (src.size_)
{
toAdd = src.head_;
src.head_ = src.head_->pNext_;
insertTail(toAdd);
src.size_--;
}
}
template<typename T>
void DoubleLinkedList<T>::outAll()
{
for (int i = 0; i < size_; i++)
{
std::cout << '[' << this[i] << "] ";
}
std::cout << std::endl;
}
template<typename T>
void DoubleLinkedList<T>::clear()
{
while (size_)
{
deleteHead();
}
}
template<typename T>
DoubleLinkedList<T>::~DoubleLinkedList()
{
clear();
}
template<typename T>
void DoubleLinkedList<T>::swap(DoubleLinkedList<T>& other) noexcept
{
std::swap(this->head_, other.head_);
std::swap(this->tail_, other.tail_);
std::swap(this->size_, other.size_);
}
template<typename T>
void DoubleLinkedList<T>::insertHead(Node<T>* x)
{
x->pNext_ = head_;
if (head_ != nullptr)
{
head_->pPrev_ = x;
}
else
{
tail_ = x;
}
head_ = x;
size_++;
}
template<typename T>
void DoubleLinkedList<T>::insertTail(Node<T>* x)
{
x->pPrev_ = tail_;
if (tail_ != nullptr)
{
tail_->pNext_ = x;
}
else
{
head_ = x;
}
tail_ = x;
size_++;
}
template<typename T>
void DoubleLinkedList<T>::deleteNode(Node<T>* x)
{
if (x == nullptr) {
throw ("DoubleLinkedList::deleteNode - incorrect node address");
}
if (x->pPrev_ != nullptr)
{
(x->pPrev_)->pNext_ = x->pNext_;
}
else
{
head_ = x->pNext_;
}
if (x->pPrev_ != nullptr)
{
(x->pNext_)->pPrev_ = x->pPrev_;
}
else
{
tail_ = x->pPrev_;
}
delete x;
size_--;
}
template<typename T>
DoubleLinkedList<T>::Node<T>* DoubleLinkedList<T>::searchNode(T data)
{
Node<T>* x = head_;
while (x != nullptr && x->data_ != data)
{
x = x->pNext_;
}
return x;
}
template<typename T>
DoubleLinkedList<T>::Node<T>* DoubleLinkedList<T>::replaceNode(Node<T>* x, T data)
{
if (x == nullptr) {
throw ("DoubleLinkedList::replaceNode - incorrect node address");
}
x->data_ = data;
return x;
}
template<typename T>
std::ostream& operator<<(std::ostream& os, DoubleLinkedList<T>& list)
{
for (int i = 0; i < list.size_; i++)
{
os<< '[' << list[i] << "] ";
}
}
int main()
{
DoubleLinkedList<int> a;
a.insertHead(40);
a.insertHead(100);
a.insertTail(20);
std::cout << a;
/*a.outAll();*/
}
Буду благодарен, если объясните, что я делаю не так.