Jeśli te dwie liniki kodu to te:
Linked_list<Node>* nowy_obiekt = new Linked_list<Node>();
Linked_list<Node*>* nowy_obiekt2 = new Linked_list<Node*>();
To ktoś wymaga coś dziwnego od ciebie.
Mamy 2020 C++11 powinno być już używane obligatoryjnie!
struct EmpltyListException : std::exception
{
const char* what() const noexcept override
{
return "List is empty";
}
};
template<typename T>
class LinkedList {
struct Node {
template<typename...Args>
Node(Args...args) : value(std::forward<Args>(args)...)
{}
std::unique_ptr<Node> next;
Node* prev = nullptr;
T value;
};
public:
LinkedList()
{
}
LinkedList(std::initializer_list<T> iniList)
{
for (const auto& x : iniList) {
emplaceBack(x);
}
}
~LinkedList() {
clear();
}
void clear() {
// loop version prevents stack overflow which could be caused by simple: head = nullptr;
for (auto p = std::move(head); p; p = std::move(p->next));
tail = nullptr;
}
template<typename...Args>
void emplaceFront(Args...args) {
auto item = std::make_unique<Node>(std::forward<Args>(args)...);
if (!head) {
tail = item.get();
} else {
head->prev = item.get();
item->next = std::move(head);
}
head = std::move(item);
}
template<typename...Args>
void emplaceBack(Args...args) {
auto item = std::make_unique<Node>(std::forward<Args>(args)...);
auto pp = tail ? &tail->next : &head;
item->prev = tail;
tail = item.get();
*pp = std::move(item);
}
void forEach(std::function<void(T&)> f)
{
for (auto p = head.get(); p; p = p->next.get())
f(p->value);
}
void forEach(std::function<void(const T&)>) const
{
for (auto p = head.get(); p; p = p->next.get())
f(p->value);
}
bool empty() const {
return head == nullptr;
}
T& front() {
thowIfEmpty();
return head->value;
}
const T& front() const{
thowIfEmpty();
return head->value;
}
T& back() {
thowIfEmpty();
return tail->value;
}
const T& back() const{
thowIfEmpty();
return tail->value;
}
private:
void thowIfEmpty() const {
if (empty()) {
throw EmpltyListException{};
}
}
private:
std::unique_ptr<Node> head;
Node* tail = nullptr;
};
https://godbolt.org/z/W68KfP