Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> r-value refs & move-semantics. что? как? для чего? 
V
    Опции темы
boostcoder
Дата 9.11.2011, 02:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



итак. что же такое r-value refs & move-semantics?

что мне известно об этом?: первое(и вроде как единственное) - позволяет получать ссылки на временные объекты.
Код

void func(type&& t) {}

...


func(type());


такой еще пример:
Код

#include <iostream>
#include <utility>
#include <vector>
#include <string>
int main()
{
    std::string str = "Hello";
    std::vector<std::string> v;
 
    // uses the push_back(const T&) overload, which means 
    // we'll incur the cost of copying str
    v.push_back(str);
    std::cout << "After copy, str is \"" << str << "\"\n";
 
    // uses the rvalue reference push_back(T&&) overload, 
    // which means no strings will copied; instead, the contents
    // of str will be moved into the vector.  This is less
    // expensive, but also means str will now be empty.
    v.push_back(std::move(str));
    std::cout << "After move, str is \"" << str << "\"\n";
 
    std::cout << "The contents of the vector are \"" << v[0]
                                         << "\", \"" << v[1] << "\"\n";
}

http://en.cppreference.com/w/cpp/utility/move

не может быть чтоб на этом польза от r-value refs & move-semantics закончилась.
поделитесь опытом, мыслями.

спасибо.
PM WWW   Вверх
azesmcar
Дата 9.11.2011, 09:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



boostcoder

Это перемещение объекта, объект может быть не копируемым, но перемещаемым. В некоторых случаях копирование объекта невозможно реализовать, зато запросто можно реализовать перемещение.
Например класс std::unique_ptr не поддерживает копирование. Он не считает количество ссылок, т.е. его копирование просто невозможно (или он должен работать как auto_ptr), зато реализовано перемещение этого объекта, что позволяет хранить std::unique_ptr в контейнерах.
PM   Вверх
boostcoder
Дата 9.11.2011, 09:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



azesmcar, но у перемещаемого объекта все равно вызывается деструктор? и если да, то что он разрушает, если данные были перемещены?
PM WWW   Вверх
azesmcar
Дата 9.11.2011, 10:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Например:
Код

#include <algorithm>

class X
{
private:
   int* data;
public:
   X():
      data(new int[1000000]) {}
   ~X()
   {
      delete data;
   }
   X(const X& other):
      data(new int[1000000])
   {
      std::copy(other.data,other.data+1000000,data);
   }
   X(X&& other):
      data(other.data)
   {
      other.data=0;
   }
};

int main()
{
   X x1;
   X x2=std::move(x1);
}

http://liveworkspace.org/code/4baf51d7d55a...835aad73d11a085

Объект перемещается, т.е. все данные переместились в другой объект, в данном случае деструктор сделает delete 0 и успокоится.
Что делает деструктор и конструктор перемещения решает программист.
PM   Вверх
boostcoder
Дата 9.11.2011, 10:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(azesmcar @  9.11.2011,  10:04 Найти цитируемый пост)
Вызывается он у перемещенного

что-то не понял...
вот к примеру:
Код

template<typename F>
void async_call(F&& f) {}

...

async_call(boost::bind(...));

т.е. async_call() возвращает управление тут же. но если функциональный объект так же, тут же будет разрушен, то когда придет время его вызвать получим ошибку сегментации. или как?

Добавлено через 1 минуту и 53 секунды
Цитата(azesmcar @  9.11.2011,  10:10 Найти цитируемый пост)
в данном случае деструктор сделает delete 0

ага. т.е. реализация деструктора должна предполагать подобное поведение?
PM WWW   Вверх
azesmcar
Дата 9.11.2011, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(boostcoder @  9.11.2011,  10:10 Найти цитируемый пост)
т.е. async_call() возвращает управление тут же. но если функциональный объект так же, тут же будет разрушен, то когда придет время его вызвать получим ошибку сегментации. или как? 

Функциональный разрушен не будет, функциональный объект был перемещен и будет разрушен после выхода из области видимости.

Добавлено через 1 минуту и 57 секунд
Цитата(boostcoder @  9.11.2011,  10:10 Найти цитируемый пост)
ага. т.е. реализация деструктора должна предполагать подобное поведение? 

точнее реализациа конструктора перемещения smile 
деструктор в моем примере ведет себя как обычно.
PM   Вверх
rumit7
Дата 9.11.2011, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 16.6.2011

Репутация: 6
Всего: 7



Цитата(boostcoder @ 9.11.2011,  09:58)
azesmcar, но у перемещаемого объекта все равно вызывается деструктор? и если да, то что он разрушает, если данные были перемещены?

Извините что вмешиваюсь, вот по этой ссылке идет вроде не плохое и достаточно подробное объяснение r-value refs & move-semantics. 

Ну и к одному из приведенному примеру дается такое объяснение: " Instead of dynamically allocating memory, the move constructor and move assignment operator simply steal it from other .  When stealing, we copy other's pointer and then null it out.  When other is destroyed, its destructor will do nothing.". 

Там есть примеры показывающие различное поведение r-value refs, а также обсуждается как работает std::move() для различных аргументов:

Цитата

·         When called with an lvalue of type string, T is deduced to be string& , so Move() takes string& (after collapsing) and returns string&& (after RemoveReference).
 
·         When called with an lvalue of type const string, T is deduced to be const string& , so Move() takes const string& (after collapsing) and returns const string&& (after RemoveReference).
 
·         When called with an rvalue of type string, T is deduced to be string , so Move() takes string&& and returns string&& .
 
·         When called with an rvalue of type const string, T is deduced to be const string , so Move() takes const string&& and returns const string&& .
 
This is how Move() preserves the type and constness of its argument, but converts lvalues into rvalues.


Это сообщение отредактировал(а) rumit7 - 9.11.2011, 10:22
PM MAIL   Вверх
boostcoder
Дата 9.11.2011, 10:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(azesmcar @  9.11.2011,  10:12 Найти цитируемый пост)
функциональный объект был перемещен и будет разрушен после выхода из области видимости

все равно не понимаю...

к примеру, r-value refs у нас нет. тогда мой пример записывался бы так:
Код

template<typename F>
void async_call(const F& f) {}

...

async_call(boost::bind(...));

т.е. тут создавался бы временный объект, внутри функции async_call() инициализировался бы другой объект, и временный объект бы разрушался. тут все понятно.

а вот с r-value что-то не понимаю смысла, если временный объект все равно создается и разрушается..

Добавлено через 1 минуту и 42 секунды
rumit7, спасибо. сейчас прочту.

PM WWW   Вверх
azesmcar
Дата 9.11.2011, 10:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(boostcoder @  9.11.2011,  10:17 Найти цитируемый пост)
а вот с r-value что-то не понимаю смысла, если временный объект все равно создается и разрушается.. 

разрушается не объект а "пустышка", а душа обьекта переселилась в другое тело и живет там в лучших традициях реинкарнации.

Это сообщение отредактировал(а) azesmcar - 9.11.2011, 10:21
PM   Вверх
boostcoder
Дата 9.11.2011, 10:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(azesmcar @  9.11.2011,  10:20 Найти цитируемый пост)
разрушается не объект а "пустышка"

ааа! вот оно как.

Цитата(azesmcar @  9.11.2011,  10:20 Найти цитируемый пост)
душа обьекта переселилась в другое тело и живет там в лучших традициях реинкарнации.

 smile 


вроде понял.. нужно усвоить.
PM WWW   Вверх
boostcoder
Дата 9.11.2011, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



azesmcar, все, понял. спасибо.

зы
с двухсотым плюсиком тебя.

PM WWW   Вверх
mes
Дата 9.11.2011, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  9.11.2011,  01:17 Найти цитируемый пост)
 позволяет получать ссылки на временные объекты.

хочу обратить внимание, что временный объект не всегда рвалуе и поэтому эти понятия не стоит смешивать.. 


Цитата(boostcoder @  9.11.2011,  01:17 Найти цитируемый пост)
не может быть чтоб на этом польза от r-value refs & move-semantics закончилась.

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



--------------------
PM MAIL WWW   Вверх
baldina
Дата 9.11.2011, 14:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата(boostcoder @  9.11.2011,  02:17 Найти цитируемый пост)
не может быть чтоб на этом польза от r-value refs & move-semantics закончилась.

оно собственно и задумывалось как средство оптимизации временных объектов, и от этого польза немалая, т.к. для обеспечения производительности раньше в некоторых случаях требовался специальный, менее красивый и простой дизайн.
Цитата(mes @  9.11.2011,  14:43 Найти цитируемый пост)
польза например наблюдается при возвращении массива из функции.. 

 smile да-да, типа того

Цитата(boostcoder @  9.11.2011,  02:17 Найти цитируемый пост)
 позволяет получать ссылки на временные объекты

Цитата(mes @  9.11.2011,  14:43 Найти цитируемый пост)
хочу обратить внимание, что временный объект не всегда рвалуе и поэтому эти понятия не стоит смешивать.. 

boostcoder видимо имеет в виду это:
http://liveworkspace.org/code/1a70c160da7c...2dbaf2a272a94a2
хотя имхо польза от этого довольно сомнительная...

PM MAIL   Вверх
boostcoder
Дата 9.11.2011, 18:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  9.11.2011,  14:43 Найти цитируемый пост)
польза например наблюдается при возвращении массива из функции

тоже вариант.
PM WWW   Вверх
borisbn
Дата 9.11.2011, 19:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Экспериментировал как-то с move-semantics:
http://liveworkspace.org/code/ad3e28d4a554...cdfe13a7b58d551
Почему-то у меня упорно не хочет вызыватся move-ctor Str( Str && other );
Что я не так делаю...
И ещё. Там создаётся 4 объекта (x, y, x и result внутри operator+), а вызывается 3 деструктора. Как это ?
И где вызвался конструктор z ?


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1491 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.