I'm currently studying data structures, I have implemented simple single linked list as shown below. I would like to know how can I improve it?#include <iostream>#include <memory>#include <cassert>template <typename T>class List {    struct node     {        T value;        std::unique_ptr<node> next;    };public:    List();    void add(T value);    T first() const;    T value(std::size_t position) const;    std::size_t length() const;    void clear();private:    std::unique_ptr<node>   mFirst;    std::size_t             mLength;};template <class T>List<T>::List()    : mFirst(nullptr)    , mLength(){}template <typename T>std::size_t List<T>::length() const{    return mLength;}template <typename T>T List<T>::first() const{    assert(mFirst != nullptr);    return mFirst->value;}template <typename T>void List<T>::add(T value){    auto next = std::move(mFirst);    mFirst = std::make_unique<node>();    mFirst->value = value;    mFirst->next = std::move(next);    mLength++;}template <class T>T List<T>::value(std::size_t position) const{    assert(mFirst != nullptr);    auto current = mFirst.get();    for (auto i = 0u; i < position; ++i)    {        current = current->next.get();    }    return current->value;}template <class T>void List<T>::clear(){    assert(mFirst != nullptr);    auto length = mLength;    for (auto i = 0u; i < length; ++i)    {        mFirst = std::move(mFirst->next);        mLength--;    }}int main(){    List<int> list;    for (int i = 0; i < 10; ++i)        list.add(i);    for (auto i = 0u; i < list.length(); ++i)        std::cout << list.value(i) << ' ';    list.clear();    std::cout << \n\n << list.length() << \n\n;}
Simple Single Linked List
c++;c++11;linked list
Choice of MembersYou currently keep a head pointer and a length. The result of this is that add is a linear operation. It would be much better to additionaly keep a tail pointer, so that add is constant time. Since linked lists do not support random access, it's questionable to have a method like T value(size_t ). If you need to index into a container, you probably don't want to use a linked list. Better to not provide it. Unfortunately, this is your only way to get anything other than the first value - which makes iteration take quadratic time! What you need to do is to do as the standard library do and add something like:struct iterator {    // basically a wrapper around node* that works as a ForwardIterator};iterator begin() { return iterator{mFirst.get()}; }iterator end() { return iterator{mLast}; }This will additionally allow everybody to use the standard library algorithms with your class. You will want a const_iterator as well, to allow for iteration over a const List<T>.Use ReferencesRight now add() takes a T and first() returns a T. For something like int, the former is OK, but the latter is still questionable. What if you want to modify the list elements? That seems like a useful operation. To that end, you should add:void add(T const& );void add(T&& );T& first();T const& first();You may also want to add an emplace, to construct values in-place:template <typename... Args>void emplace(Args&&...);You may want to rename first to front for convention. Similarly length to size.ClearingSince you are using smart pointers for your list, clearing is very simple. You don't need a loop at all:template <class T>void List<T>::clear(){    mFirst.clear();    mLast = nullptr;    mLength = 0;}