E.g., I have an empty
function to clear a linked list:
void empty(Node* head) {
if (head->next) { empty(head->next); }
delete head;
head = nullptr;
}
But then I created a class for the linked list, so now I don't need to pass the head
argument:
void empty() {
if (head->next) { empty(head->next); }
delete head;
head = nullptr;
}
But empty(head->next)
line is obviously wrong as empty
doesn't take any arguments. The idea comes to my mind to create a function inside a function (with lambda), something like this:
void empty() {
std::function<void(Node*)> emptyWrapper = [&] (Node* l_head) {
if (l_head->next) { emptyWrapper(l_head->next); }
delete l_head;
l_head = nullptr;
};
emptyWrapper(head);
}
But I'm wondering if there's any better way to do it. Lambdas became kind of idee fixe for me recently.
A general approach is to declare a public member function that in turn calls a private static recursive member function.
Pay attention that the name empty
sounds confusing. It is better to name the function for example like clear
.
Here you are
#include <functional>
//...
class List
{
public:
//...
void clear()
{
clear( head );
}
private:
static void clear( Node * &head )
{
if ( head )
{
delete std::exchange( head, head->next );
clear( head );
}
}
//...
}
The same approach can be used without defining an auxiliary static function.
void clear()
{
if ( head )
{
delete std::exchange( head, head->next );
clear();
}
}
Here is a demonstrative program.
#include <iostream>
#include <iomanip>
#include <functional>
template <typename T>
class List
{
private:
struct Node
{
T data;
Node *next;
} *head = nullptr;
public:
void push_front( const T &data )
{
head = new Node { data, head };
}
friend std::ostream & operator <<( std::ostream &os, const List &list )
{
for ( Node *current = list.head; current; current = current->next )
{
os << current->data << " -> ";
}
return os << "null";
}
bool empty() const { return head== nullptr; }
void clear()
{
if ( head )
{
delete std::exchange( head, head->next );
clear();
}
}
};
int main()
{
List<int> list;
const int N = 10;
for ( int i = N; i != 0; )
{
list.push_front( i-- );
}
std::cout << list << '\n';
list.clear();
std::cout << "list is empty " << std::boolalpha << list.empty() << '\n';
return 0;
}
The program output is
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> null
list is empty true