powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / move- семантика: как передать unique_ptr?
13 сообщений из 13, страница 1 из 1
move- семантика: как передать unique_ptr?
    #39638636
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
void OpenBinFileForWrite(std::unique_ptr<std::ofstream> File, cstring& FileName);

void WriteArrayToBinFile(const VariativeData& Settings, cstring& NameFile) const
{
             auto File = std::make_unique<std::ofstream>;

            //open file for write
            OpenBinFileForWrite(std::move(File), NameFile);//ОШИБКА!!!
}


Код: plaintext
1.
ошибка: could not convert ‘std::move(File)’ from ‘std::remove_reference<std::unique_ptr<std::basic_ofstream<char> > (*&)()>::type {aka std::unique_ptr<std::basic_ofstream<char> > (*)()}’ to ‘std::unique_ptr<std::basic_ofstream<char> >’
             OpenBinFileForWrite(std::move(File), NameFile);

Я пробовал в функции OpenBinFileForWrite принимать по rvalue- ссылке &&. Но все равно получаю ошибки.
...
Рейтинг: 0 / 0
move- семантика: как передать unique_ptr?
    #39638639
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если вместо:
Код: plaintext
1.
auto File = std::make_unique<std::ofstream>;



написать:
Код: plaintext
1.
2.
std::ofstream* pFile = new std::ofstream;
std::unique_ptr<std::ofstream> File(pFile);



то все работает. Причем принимающая функция берет хоть по значению, хоть по правой ссылке- работает...

Я правильно понимаю:

Правая ссылка- это точно такая же ссылка, как и левая, только для временных объектов. Поэтому при ее использовании передача управления произойдет не в момент вызова метода OpenBinFileForWrite, а в момент, когда в методе произойдет явная передача управления. В противном случае (прием в методе по значению) при инициализации параметров метода OpenBinFileForWrite сразу произойдет передача управления и старый объект разрушится.

???

p.s. На просторах интернета нет ни одной нормальной русскоязычной информации по правым ссылкам. Все они друг другу противоречат и рассматривают какие- то частности, а не простые, но фундаментальные вопросы, как передача временного значения в функцию.
...
Рейтинг: 0 / 0
move- семантика: как передать unique_ptr?
    #39638641
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlekseySQL
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
void OpenBinFileForWrite(std::unique_ptr<std::ofstream> File, cstring& FileName);

void WriteArrayToBinFile(const VariativeData& Settings, cstring& NameFile) const
{
             auto File = std::make_unique<std::ofstream>;

            //open file for write
            OpenBinFileForWrite(std::move(File), NameFile);//ОШИБКА!!!
}


Код: plaintext
1.
ошибка: could not convert ‘std::move(File)’ from ‘std::remove_reference<std::unique_ptr<std::basic_ofstream<char> > (*&)()>::type {aka std::unique_ptr<std::basic_ofstream<char> > (*)()}’ to ‘std::unique_ptr<std::basic_ofstream<char> >’
             OpenBinFileForWrite(std::move(File), NameFile);

Я пробовал в функции OpenBinFileForWrite принимать по rvalue- ссылке &&. Но все равно получаю ошибки.
Ты круглые скобки у make_unique, случаем, не забыл?
...
Рейтинг: 0 / 0
move- семантика: как передать unique_ptr?
    #39638643
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
NekZ, спасибо, меня просто подсказка напугала (после ввода круглых скобок я получал подчеркивание и подсказку "слишком мало параметров"). Так работает.
...
Рейтинг: 0 / 0
move- семантика: как передать unique_ptr?
    #39638645
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlekseySQL,

А вот напиши ты тип явно std::unique_ptr<std::ofstream>, то сразу бы понял в чём ошибка ;-) В этом недостаток auto, так что будь внимателен, когда используешь его.
...
Рейтинг: 0 / 0
move- семантика: как передать unique_ptr?
    #39638648
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AlekseySQLЯ правильно понимаю:

Правая ссылка- это точно такая же ссылка, как и левая, только для временных объектов. Поэтому при ее использовании передача управления произойдет не в момент вызова метода OpenBinFileForWrite, а в момент, когда в методе произойдет явная передача управления. В противном случае (прием в методе по значению) при инициализации параметров метода OpenBinFileForWrite сразу произойдет передача управления и старый объект разрушится.

???

Теперь я все понял!

Так работает:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
void OpenBinFileForWrite(std::unique_ptr<std::ofstream>&& File, cstring& FileName);
void WriteArrayToBinFile(const VariativeData& Settings, cstring& NameFile) const
{
             auto File = std::make_unique<std::ofstream>;

            //open file for write
            OpenBinFileForWrite(std::move(File), NameFile);
            File->write((char*) &Quantity, sizeof(uint32));//РАБОТАЕТ!!!
}



А так НЕ работает:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
void OpenBinFileForWrite(std::unique_ptr<std::ofstream> File, cstring& FileName);
void WriteArrayToBinFile(const VariativeData& Settings, cstring& NameFile) const
{
             auto File = std::make_unique<std::ofstream>;

            //open file for write
            OpenBinFileForWrite(std::move(File), NameFile);
            File->write((char*) &Quantity, sizeof(uint32));//ОШИБКА!!! File = (null)
}



Другими словами, правые ссылки позволяет передать временное значение без вызовов конструктора перемещения и/ или перемещающего оператора присваивания. А значит исходная переменная не зануляется. Вот зачем они нужны!!! Этого вы нигде не прочитаете.
...
Рейтинг: 0 / 0
move- семантика: как передать unique_ptr?
    #39638652
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlekseySQLДругими словами, правые ссылки позволяет передать временное значение без вызовов конструктора перемещения и/ или перемещающего оператора присваивания. А значит исходная переменная не зануляется .
Значение не зануляется самим фактом передачи ссылки.
Но если вы передали rv-ссылку в функцию, то вы уже не можете рассчитывать что значение сохранится. Хотя конечно никто не обязывает функцию что либо делать с переданным значением.
...
Рейтинг: 0 / 0
move- семантика: как передать unique_ptr?
    #39638786
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyЗначение не зануляется самим фактом передачи ссылки.
Но если вы передали rv-ссылку в функцию, то вы уже не можете рассчитывать что значение сохранится. Хотя конечно никто не обязывает функцию что либо делать с переданным значением.

В том- то и фишка:
1. Если принимаем по значению, то будет вызван оператор перемещающего копирования, который как правило переданный в него параметр зануляет (освобождает ресурсы). Т.е. зануление происходит ВСЕГДА.
2. Если мы принимаем по правой ссылке, то это по смыслу тоже самое, как передать обычный указатель или обычную ссылку (которые сами передаются по значению). При этом передается адрес, а не сама переменная, поэтому никаких конструкторов не вызывается и потому переданная переменная не теряет значение из-за действий конструктора. Т.е. зануление происходит, если в принимающей функции (или передавая ниже по стеку) мы явно вызовем перемещения.

Для некопируемых (но перемещаемых) объектов это очень важно: их нужно отдавать в функции как правые ссылки (с помощью std::move), принимать как правые ссылки (с помощью &&), но в принимающей функции ни в коем случае не перемещать: потому что по сути мы работаем с исходной переменной и ее перемещение занулит исходную переменную.
...
Рейтинг: 0 / 0
move- семантика: как передать unique_ptr?
    #39638790
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlekseySQL,

&& и & ссылки ничем не отличаются на принимающей стороне.
Разница только в том, что туда можно передать.
...
Рейтинг: 0 / 0
move- семантика: как передать unique_ptr?
    #39638876
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyAlekseySQL,

&& и & ссылки ничем не отличаются на принимающей стороне.
Разница только в том, что туда можно передать.

Ок.
...
Рейтинг: 0 / 0
move- семантика: как передать unique_ptr?
    #39638878
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyAlekseySQL,

&& и & ссылки ничем не отличаются на принимающей стороне.
Разница только в том, что туда можно передать.

Если принимать по константной ссылке (как левой, так и правой), то программа тоже работает без ошибок.

Какую ссылку лучше выбрать, если принимающая сторона работает с константным объектом? По логике лучше прямо это показать, использую левую ссылку: правые для изменений, левые для константных объектов. Я прав?
...
Рейтинг: 0 / 0
move- семантика: как передать unique_ptr?
    #39639006
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyAlekseySQL,

&& и & ссылки ничем не отличаются на принимающей стороне.
Разница только в том, что туда можно передать.

Если принимать по константной ссылке (как левой, так и правой), то программа тоже работает без ошибок.

Какую ссылку лучше выбрать, если принимающая сторона работает с константным объектом? По логике лучше прямо это показать, использую левую ссылку: правые для изменений, левые для константных объектов. Я прав?
...
Рейтинг: 0 / 0
move- семантика: как передать unique_ptr?
    #39639137
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZВ этом недостаток auto, так что будь внимателен, когда используешь его.не надо использовать auto где попало. Он сделан не для того, чтобы сокращать длинные декларации. Для этого есть using, надо использовать его. Уже не первый раз тут(и не тут) пишут про ошибки, которые возникли из-за того, что автор использовал auto, чтобы "упростить" код.
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / move- семантика: как передать unique_ptr?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]