@newmersedez

Как правильно работать с rvalue ссылкой в качестве параметра метода класса?

Пишу шаблонный класс двусвязного списка. Возникло два вопроса. Первый вопрос: правильно ли я присвоил rvalue значение в поле data класса List_node? (строка 70 в реализации списка). Второй вопрос: В чем заключается ошибка? Компилятор ругается на строку 138, в которой я создаю новый элемент двусвязного списка. Компилировал с помощью утилиты make, но это особо ничего не меняет, использовал только правило make all, в котором просто компилирую файлики через g++.

Частичная реализация шаблонного класса двусвязного списка:
#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:
#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);
}
  • Вопрос задан
  • 53 просмотра
Пригласить эксперта
Ответы на вопрос 1
0hquazEd
@0hquazEd
Код вообще странный, но вместо new_node->data = &value; вам стоило использовать new_node->data = std::forward<T>(value);. Советую почитать про универсальные ссылки. Здесь или же в книге Скотта Майерса. Вкратце эта ссылка становится rvalue, если инициализирована rvalue-значением и lvalue, если инициализирована lvalue-значением
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы