N
N
newmersedez2021-05-08 01:11:44
C++ / C#
newmersedez, 2021-05-08 01:11:44

What is the correct way to work with rvalue reference as a class method parameter?

I am writing a template class for a doubly linked list. There were two questions. First question: did I correctly assign the rvalue value to the data field of the List_node class? (line 70 in the list implementation). Second question: What is the error? The compiler complains about line 138, in which I create a new element of a doubly linked list. I compiled using the make utility, but it doesn't really change anything, I just used the make all rule, in which I just compile the files using g++.

Partial implementation of the doubly linked list template class:

#pragma once

#include <ostream>
#include <list>

/* Doubly linked list node class */

template <typename T>
class	List_node
{
private:
  T			*data;
  List_node	*prev_ptr;
  List_node	*next_ptr;

template <typename U> friend class List;
};

/* Doubly linked list class */

template <typename T> 
class	List
{
private:
  List_node<T>	*head;

  List_node<T>	*__create_node(T&& value);

public:
  List();
  ~List();

  size_t			size();
  bool			empty();
  void			clear();
  void			print(std::ostream& outstream);
  void			push_back(T&& value);
};

template <typename T>
List<T>::List()
{
  head = nullptr;
}

template <typename T>
List<T>::~List()
{
  List_node<T>	*temp_ptr;

  if (head != nullptr)
  {
    while (head->next_ptr != nullptr)
    {
      temp_ptr = head;
      head = head->next_ptr;
      delete temp_ptr;
    }
  }
}

template <typename T>
List_node<T>	*List<T>::__create_node(T&& value)
{
  List_node<T>	*new_node;
  
  new_node = new List_node<T>;
  if (new_node)
  {
    new_node->data = &value;
    new_node->next_ptr = nullptr;
    new_node->prev_ptr = nullptr;
  }
  return (new_node);
}

template <typename T>
bool	List<T>::empty()
{
  return (head == nullptr);
}

template <typename T>
size_t	List<T>::size()
{
  List_node<T>	*temp_ptr;
  size_t			size = 0;

  if (head == nullptr)
    return (0);
  temp_ptr = head;
  while (temp_ptr != nullptr)
    size++;
  return (size);
}

template <typename T>
void	List<T>::clear()
{
  List_node<T>	*temp_ptr;

  if (head != nullptr)
  {
    while (head->next_ptr != nullptr)
    {
      temp_ptr = head;
      head = head->next_ptr;
      delete temp_ptr;
    }
  }
  head = nullptr;
}

template <typename T>
void	List<T>::print(std::ostream& outstream)

{
  List_node<T>	*temp_ptr;

  if (!head)
    return ;
  temp_ptr = head;
  while (temp_ptr->next_ptr != nullptr)
  {
    outstream << *(temp_ptr->data) << " ";
    temp_ptr = temp_ptr->next_ptr;
  }
  outstream << "\n";
}

template <typename T>
void	List<T>::push_back(T&& value)
{
  List_node<T>	*new_node;
  List_node<T>	*curr_node;
  List_node<T>	*prev_node;

  new_node = __create_node(value);
  if (new_node != nullptr)
  {
    if (!head)
    {
      head = new_node;
      return ;
    }
    else
    {
      curr_node = head;
      while (curr_node->next_ptr != nullptr)
      {
        prev_node = curr_node;
        curr_node = curr_node->next_ptr;
      }
      curr_node->next_ptr = new_node;
      if (curr_node != head)
        curr_node->prev_ptr = prev_node;
    }
  }
}


main.cpp function:
#include <iostream>
#include "./headers/doubly_linked_list.hpp"

int	main()
{
  List<int>	new_list;

  new_list.push_back(12);
  new_list.push_back(14);
  new_list.push_back(1552);

  new_list.print(std::cout);

  return (0);
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
C
cunion, 2021-05-10
@0hquazEd

The code is generally strange, but instead new_node->data = &value;you should have used . I advise you to read about universal links. Here or in the book by Scott Myers. In short, this reference becomes an rvalue if initialized to an rvalue and an lvalue if initialized to an lvalue. new_node->data = std::forward<T>(value);

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question