Detect loop in linked list (Floyd cycle finding algorithm) I have written this code Floyd Cycle finding algorithm. The methods I have used are createLoop() , doesLoopExist(), lengthOfLoop() and insert().
I want to optimise this code and improve using advanced C++.

#include &lt;iostream&gt;

template &lt;class T&gt;
class LinkedList
{
  struct Node
  {
    T data;
    Node * next;
    Node(T value) : data(value), next(nullptr) {}
  };
  Node *head;

public:
  LinkedList() : head(nullptr) {}
  ~LinkedList();
  void insert(T);
  void createLoop(int);
  bool doesLoopExist();
  int lengthOfLoop();
};

template &lt;class T&gt;
void LinkedList&lt;T&gt;::insert(T data)
{
  Node *node = new Node(data);
  Node *tmp = head;
  if(tmp == nullptr)
  {
    head = node;
  }
  else
  {
    while(tmp-&gt;next != nullptr)
    {
      tmp = tmp-&gt;next;
    }
    tmp-&gt;next = node;
  }
}

template &lt;class T&gt;
void LinkedList&lt;T&gt;::createLoop(int n)
{
  Node *tmp = head;
  Node *tail = head;
  for(int i = 0; i &lt; n-1; i++)
  {
    tmp = tmp-&gt;next;
  }

  while(tail-&gt;next != nullptr)
  {
    tail = tail-&gt;next;
  }
  tail-&gt;next = tmp;
}

template &lt;class T&gt;
bool LinkedList&lt;T&gt;::doesLoopExist()
{
  Node *slowPtr = head;
  Node *fastPtr = head;

  while(slowPtr &amp;&amp; fastPtr &amp;&amp; fastPtr-&gt;next)
  {
    slowPtr = slowPtr-&gt;next;
    fastPtr = fastPtr-&gt;next-&gt;next;

    if(slowPtr == fastPtr)
    {
      return true;
    }
  }
  return false;
}

template &lt;class T&gt;
int LinkedList&lt;T&gt;::lengthOfLoop()
{
  int count = 0, loopExist = 0;
  Node *slowPtr = head;
  Node *fastPtr = head;
  while(slowPtr &amp;&amp; fastPtr &amp;&amp; fastPtr-&gt;next)
  {
    slowPtr = slowPtr-&gt;next;
    fastPtr = fastPtr-&gt;next-&gt;next;

    if(slowPtr == fastPtr)
    {
      loopExist = 1;
      break;
    }
  }
  if(loopExist)
  {
    fastPtr = fastPtr-&gt;next;
    count++;
    while(slowPtr != fastPtr)
    {
      fastPtr = fastPtr-&gt;next;
      count++;
    }
    return count;
  }
  return 0;
}

template &lt;class T&gt;
LinkedList&lt;T&gt;::~LinkedList()
{
  Node *tmp = nullptr;
  while(head)
  {
    tmp = head;
    head = head-&gt;next;
    delete tmp;
  }
  head = nullptr;
}

int main()
{
  LinkedList&lt;char&gt; ll1;
  ll1.insert('p');
  ll1.insert('r');
  ll1.insert('o');
  ll1.insert('g');
  ll1.insert('r');
  ll1.insert('a');
  ll1.insert('m');
  ll1.insert('m');
  ll1.insert('e');
  ll1.insert('r');

  int nodeNumber = 5;
  //Node number starts from 1

  ll1.createLoop(nodeNumber);
  bool result = ll1.doesLoopExist();
  if(result == true)
  {
    std::cout &lt;&lt;"Loop exist in the Linked List\n";
  }
  else
  {
    std::cout &lt;&lt;"Loop does not exist in the Linked List\n";
  }

  int len = ll1.lengthOfLoop();
  std::cout &lt;&lt; "Length of Loop is " &lt;&lt; len &lt;&lt;"\n";

  return 0;
}
DRY. The first loop of lengthOfLoop is literally identical to doesLoopExist. Replace it with

    loopExist = doesLoopExist();


This also hints that doesLoopExist should be Node * doesLoopExist(), and return a node on the loop or nullptr.
The destructor invokes UB when applied to the list with a loop. At the end of the loop the next pointer points to an already deleted node.
insert should be better called append.