0 / 0 / 0
Регистрация: 14.05.2020
Сообщений: 50
|
|||||||||||
1 | |||||||||||
Шаблонный класс двусвязного списка и rvalue ссылки08.05.2021, 01:07. Показов 3051. Ответов 14
Пишу шаблонный класс двусвязного списка. Возникла два вопроса. Первый вопрос: правильно ли я присвоил rvalue значение в поле data класса List_node? (строка 70 в реализации списка). Второй вопрос: В чем заключается ошибка? Компилятор ругается на строку 138, в которой я создаю новый элемент двусвязного списка. Компилировал с помощью утилиты make
Код
rm -f ./objects/main.o rm -f main g++ -Wall -Wextra -Werror -g -std=c++17 -o objects/main.o -c main.cpp In file included from main.cpp:2: ./headers/doubly_linked_list.hpp: In instantiation of ‘void List<T>::push_back(T&&) [with T = int]’: main.cpp:8:23: required from here ./headers/doubly_linked_list.hpp:138:11: error: cannot bind rvalue reference of type ‘int&&’ to lvalue of type ‘int’ 138 | new_node = __create_node(value); ./headers/doubly_linked_list.hpp:63:42: note: initializing argument 1 of ‘List_node<T>* List<T>::__create_node(T&&) [with T = int]’ 63 | List_node<T> *List<T>::__create_node(T&& value) | ~~~~^~~~~ make: *** [Makefile:24: objects/main.o] Error 1
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
|
|
08.05.2021, 01:07 | |
Ответы с готовыми решениями:
14
Есть класс двусвязного списка(head,tail),как разделить его на два списка Создать динамический класс Route на основе двусвязного списка, где каждый элемент типа stop (стоп). Класс должен содержа Класс, шаблонный класс, на основе списка
|
129 / 81 / 49
Регистрация: 10.01.2020
Сообщений: 293
|
||||||
08.05.2021, 09:09 | 2 | |||||
newmersedez, 138 строка:
1
|
Вездепух
![]() ![]() 10428 / 5698 / 1552
Регистрация: 18.10.2014
Сообщений: 14,067
|
|
08.05.2021, 09:16 | 3 |
Нет, не правильно. Автор очевидно попытался воспользоваться rvalue ссылками для того, чтобы обойти ограничения языка и упростить самому себе создание мертвых указателей "в никуда". Именно такие мертвые указатели "в никуда" и создаются в этом коде.
Почему элементы списка содержат указатели на данные? Откуда возникла такая странная идея хранить указатели? Куда эти указатели будут указывать? Кто и как будет заботиться о времени жизни указуемых данных? Пока что написана полная бессмыслица.
1
|
129 / 81 / 49
Регистрация: 10.01.2020
Сообщений: 293
|
|||||||||||
08.05.2021, 09:27 | 4 | ||||||||||
newmersedez, Пример структуры реализации шаблонного двухсвязного списка:
Node:
Также, тут нет деструктора, но он обязателен.
1
|
0 / 0 / 0
Регистрация: 14.05.2020
Сообщений: 50
|
|
08.05.2021, 13:02 [ТС] | 5 |
Такое задание в курсовой, нельзя хранить копии. Если буду хранить копии, заставят переписать
Добавлено через 1 минуту Тогда как правильно присвоить значение rvalue ссылки в поле класса?
0
|
129 / 81 / 49
Регистрация: 10.01.2020
Сообщений: 293
|
|
08.05.2021, 13:03 | 6 |
TheCalligrapher,
С другой стороны это верно, ведь если в данных узла будет лежать, скажем, большая структура данных, то каждый раз для нее будет задействован конструктор копирования, что увеличит расход памяти программы.
1
|
16495 / 8988 / 2205
Регистрация: 30.01.2014
Сообщений: 15,603
|
|
08.05.2021, 13:19 | 7 |
![]() Решение
Тогда вам надо определиться где будут храниться эти экземпляры ваших данных, чтобы указатели на них можно было сохранять в списке.
Т.е. ответить для себя вот на эти вопросы: Добавлено через 14 минут Хранить отдельно указатели на данные эффективно только если эти данные у нас уже где-то созданы и живут по крайней мере столько же, сколько сам список. Если ТС как-то это обеспечит, тогда ок. В остальных случаях это не будет ничем лучше, а вот хуже - запросто.
1
|
0 / 0 / 0
Регистрация: 14.05.2020
Сообщений: 50
|
|
08.05.2021, 13:36 [ТС] | 8 |
Да, у меня в дальнейшем в этом списке будут храниться объекты другого класса, скажем так, таких объектов может быть больше 20 миллионов. Поэтому я и храню указатель, чтобы не хранить копию объекта и сам объект
0
|
129 / 81 / 49
Регистрация: 10.01.2020
Сообщений: 293
|
|
08.05.2021, 13:39 | 9 |
newmersedez, Тогда почему бы вам шаблонно не задать указательный тип. List<Type*> lst; где Type - нужный вам тип.
1
|
16495 / 8988 / 2205
Регистрация: 30.01.2014
Сообщений: 15,603
|
|
08.05.2021, 13:40 | 10 |
newmersedez, а где эти 20 миллионов объектов тогда будут храниться?
1
|
0 / 0 / 0
Регистрация: 14.05.2020
Сообщений: 50
|
|
08.05.2021, 13:44 [ТС] | 11 |
Думаю, что вы правы
Добавлено через 2 минуты Ну скорее всего не так много, но сам список будет достаточно большим, поэтому и решил указатель хранить уже на существующие обьекты
0
|
16495 / 8988 / 2205
Регистрация: 30.01.2014
Сообщений: 15,603
|
|
08.05.2021, 13:49 | 12 |
Это нормально, но вы все-таки должны определиться где они реально существовать будут. От этого зависит корректное выполнение вашего задания.
1
|
Вездепух
![]() ![]() 10428 / 5698 / 1552
Регистрация: 18.10.2014
Сообщений: 14,067
|
|
08.05.2021, 17:21 | 13 |
![]() Решение
Почему мы только сейчас узнаем детали задания?
Это какая-то дичь. Во-первых, контейнер всегда будет хранить копии. Копии чего-то: копии объектов или копии указателей на объекты. Это всегда будут копии. Вопрос лишь что за копии это будут. Во-вторых, ваш контейнер параметризован параметром T - типом хранимых данных. Если вы хотите хранить в вашем контейнере указатели - пожалуйста, храните, никто вам не запретит. Но для этого не нужно прошивать эту "указательность" прямо в реализацию шаблона. Для это достаточно просто использовать указательный тип в качестве T при инстанцировании шаблона, точно так же как это делается со стандартными контейнерами.Например, стандартный контейнер std::list<T> хранит в своих элементах значения типа T , а не T * . Тем не менее, никто мне не запрещает создать std::list<int *> - список, который будет хранить указатели. Чем вас не устраивает такой, намного более логичный подход?В-третьих, если вам по какой-то дикой причине захотелось реализовать контейнер с намертво прошитой в нем "указтельностью" хранимых данных, то флаг вам в руки. Но при чем здесь вообще какие-то "rvalue ссылки"? Откуда они тут взялись и зачем вы их сюда приплели? Ваш контейнер хранит указатели. Ну так и пишите все в терминах указателей. Никаких "rvalue ссылок" тут и в помине быть не должно. В-четвертых, как вам уже сказали не раз, как бы вы это все ни реализовывали, если ваш контейнер хранит указатели, то обеспечивать правильное время время жизни объектов, на которые указывают ваши указатели - ваша обязанность. В том коде, который вы привели, вы пытаетесь хранить указатели на временные объекты, т.е на объекты, которые уничтожаются сразу же после создания, оставляя за собой "мертвые" указатели. Вот эти "мертвые" указатели вы и пытаетесь хранить. Это бессмысленно и неработоспособно. И никакое "присваивание значения rvalue ссылки" это не исправит.
1
|
0 / 0 / 0
Регистрация: 14.05.2020
Сообщений: 50
|
|
08.05.2021, 18:12 [ТС] | 14 |
Я понял свою ошибку. Просто решил поэкспериментировать и понять, что же такое rvalue ссылки, однако эксперимент неудачный. Не до конца приходит понимание rvalue ссылок, как они работают, и когда стоит их применять,а когда нет. Есть ли какой-нибудь хороший источник, где можно изучить эту тему? Искал, что-то уже читал, но как-то все равно не укладывается в голове
0
|
16495 / 8988 / 2205
Регистрация: 30.01.2014
Сообщений: 15,603
|
|
08.05.2021, 19:19 | 15 |
1
|
08.05.2021, 19:19 | |
Помогаю со студенческими работами здесь
15
как переделать шаблонный класс-стек в шаблонный класс-очередь ! Создать шаблонный класс библиотека на основе односвязного списка Динамический класс на основе двусвязного списка(перевод кода с Java на С++) Зачем нужны rvalue ссылки, если есть универсальные ссылки Шаблонный класс: упорядоченный стек на основе связного списка в динамической памяти Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |