Lecture Notes: 18 A ConsList in C++
··2 mins
LazyVim Book #
https://lazyvim-ambitious-devs.phillips.codes/course/chapter-1/
A List in C++ #
list.hh #
#ifndef LIST_HH
#define LIST_HH
#include <memory>
#include <string>
// not great practice, but easy for examples
using namespace std;
template <typename T>
class ListBase {
public:
// a pure virtual function will never be called
// and will always be dynamically dispatched
virtual bool is_empty() = 0;
virtual int length() = 0;
};
template <typename T>
using List = unique_ptr<ListBase<T>>;
template <typename T>
class ListEmpty : public ListBase<T> {
public:
bool is_empty() { return false; }
int length() { return 0; }
};
template <typename T>
class ListCell : public ListBase<T> {
public:
const T head;
const List<T> tail;
ListCell(T hd, List<T> tl)
: head(hd)
, tail(std::move(tl))
{
}
bool is_empty() { return true; }
int length() { return 1 + tail->length(); }
};
template <typename T>
List<T>
cons(T hd, List<T> tl)
{
return make_unique<ListCell<T>>(hd, tl);
}
List<string> cons(const char* hd, List<string> tl);
template <typename T>
List<T>
empty()
{
return make_unique<ListEmpty<T>>();
}
#endif
list.cc #
#include "list.hh"
// This needs to be in the .cc file, so it doesn't
// get included twice because it's not a template.
List<string>
cons(const char* hd, List<string> tl)
{
return make_unique<ListCell<string>>(string(hd), std::move(tl));
}
main.cc #
#include "list.hh"
// Good practice to include system headers last, so
// project headers can't depend on them unexpectedly.
#include <iostream>
#include <string>
int main(int argc, char* argv[])
{
List<string> xs = cons("foo", cons("bar", cons("baz", empty<string>())));
cout << xs->length() << endl;
// part 2
// List<string> ys = cons("aa", cons("bb", xs->tail));
// cout << ys->length() << endl;
return 0;
}