Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > r-value refs & move-semantics. что? как? для чего?


Автор: boostcoder 9.11.2011, 02:17
итак. что же такое 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 закончилась.
поделитесь опытом, мыслями.

спасибо.

Автор: azesmcar 9.11.2011, 09:46
boostcoder

Это перемещение объекта, объект может быть не копируемым, но перемещаемым. В некоторых случаях копирование объекта невозможно реализовать, зато запросто можно реализовать перемещение.
Например класс std::unique_ptr не поддерживает копирование. Он не считает количество ссылок, т.е. его копирование просто невозможно (или он должен работать как auto_ptr), зато реализовано перемещение этого объекта, что позволяет хранить std::unique_ptr в контейнерах.

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

Автор: azesmcar 9.11.2011, 10:10
Например:
Код

#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/4baf51d7d55ab0104835aad73d11a085

Объект перемещается, т.е. все данные переместились в другой объект, в данном случае деструктор сделает delete 0 и успокоится.
Что делает деструктор и конструктор перемещения решает программист.

Автор: boostcoder 9.11.2011, 10:10
Цитата(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

ага. т.е. реализация деструктора должна предполагать подобное поведение?

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

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

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

точнее реализациа конструктора перемещения smile 
деструктор в моем примере ведет себя как обычно.

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

Извините что вмешиваюсь, вот по этой http://blogs.msdn.com/b/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx идет вроде не плохое и достаточно подробное объяснение 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.

Автор: boostcoder 9.11.2011, 10:17
Цитата(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, спасибо. сейчас прочту.

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

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

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

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

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

 smile 


вроде понял.. нужно усвоить.

Автор: boostcoder 9.11.2011, 12:24
azesmcar, все, понял. спасибо.

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

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

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


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

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

Автор: baldina 9.11.2011, 14:52
Цитата(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/1a70c160da7c185c82dbaf2a272a94a2
хотя имхо польза от этого довольно сомнительная...

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

тоже вариант.

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

Автор: mes 9.11.2011, 19:24
Цитата(borisbn @  9.11.2011,  18:04 Найти цитируемый пост)
Что я не так делаю...

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

Добавлено через 1 минуту и 20 секунд
Цитата(borisbn @  9.11.2011,  18:04 Найти цитируемый пост)
 Там создаётся 4 объекта

это по старым правилам smile

Автор: baldina 9.11.2011, 19:32
Цитата(borisbn @  9.11.2011,  19:04 Найти цитируемый пост)
Там создаётся 4 объекта (x, y, x и result внутри operator+), а вызывается 3 деструктора. Как это ?

там всего три объекта, погляди на адреса. result и z одно и то же.

что бы он вызвался, укажи семантику явно 
Код

Str z( move(x + y) );


Добавлено через 4 минуты и 18 секунд
Цитата(baldina @  9.11.2011,  19:32 Найти цитируемый пост)
result и z одно и то же.

это NRVO отработало. велик могучий языка...

Добавлено через 6 минут и 1 секунду
оказывается уже ответили((

Автор: borisbn 9.11.2011, 19:40
mes, baldina, спасибо за ответы, но
1) я хочу, чтобы move-конструктор вызывался автоматически, поэтому не хочу использовать std::move()
2) boostcoder говорит, что на LWS оптимизация выключена, а вы говорите, что
Цитата(mes @  9.11.2011,  19:24 Найти цитируемый пост)
компилятор позволяет себе не переносить из временого в целевой, а сразу использовать целевой объект для результата.

Цитата(baldina @  9.11.2011,  19:32 Найти цитируемый пост)
result и z одно и то же.

или это не имеет отношения к оптимизации ?
тогда вопрос снят

Автор: mes 9.11.2011, 19:44
Цитата(borisbn @  9.11.2011,  18:40 Найти цитируемый пост)
или это не имеет отношения к оптимизации ?

не имеет, это не оптимизация, а перенос при инициализации.. 

некий аналог этому из недалекого прошлого :
Код

Str str = Str ("any");

так же создается только один объект..

Цитата(borisbn @  9.11.2011,  18:40 Найти цитируемый пост)
я хочу, чтобы move-конструктор вызывался автоматически, поэтому не хочу использовать std::move()

делайте перенос не при инициализации, а при присвоении..

Автор: W4FhLF 5.3.2012, 14:13
Цитата(azesmcar @ 9.11.2011,  10:10)
Например:
Код

#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/4baf51d7d55ab0104835aad73d11a085

Объект перемещается, т.е. все данные переместились в другой объект, в данном случае деструктор сделает delete 0 и успокоится.
Что делает деструктор и конструктор перемещения решает программист.

Это получается как только я вызвал move constructor я уже объектом больше пользоваться не могу потому что данные были перемещены? Разве это не ведёт к понтенциальным ошибкам? Т.е. я должен теперь "запомнить", что объект был перемещён и больше его не трогать.

Автор: boostcoder 5.3.2012, 15:55
Цитата(W4FhLF @  5.3.2012,  14:13 Найти цитируемый пост)
я уже объектом больше пользоваться не могу потому что данные были перемещены?

угу.

Цитата(W4FhLF @  5.3.2012,  14:13 Найти цитируемый пост)
Разве это не ведёт к понтенциальным ошибкам?

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

Автор: bsa 5.3.2012, 17:54
Цитата(W4FhLF @  5.3.2012,  15:13 Найти цитируемый пост)
Т.е. я должен теперь "запомнить", что объект был перемещён и больше его не трогать. 

объект, который подпадает под rvlaue-reference по любому ты использовать больше не сможешь. В простом случае, это правая часть выражения: a = c + b. Ты по любому после присваивания не сможешь воспользоваться временным объектом.
А если у тебя остаются возможности им воспользоваться, то он не является rvalue и, соответственно, не подпадает под действие перемещающего конструктора.

Автор: Sahab 13.4.2012, 19:23
Можно ли пользоваться исходным объектом (откуда перемещали) после его перемещения?

http://liveworkspace.org/code/3c9358e9ddaef476ffd6df109b6ea1cd

Код

#include <algorithm>
#include <iostream>

class X
{
private:
   int* data;
public:
   X():
      data(new int[1000000]) {
            std::cout << "сtor()" << std::endl;
      }
   ~X()
   {
      std::cout << "~dtor()" << std::endl;
      delete data;
   }
   
   void print() {
      std::cout << this << ", " << &data[0] << std::endl;
   }
   
   X(const X& other):
      data(new int[1000000])
   {
      std::cout << "copy()" << std::endl;
      std::copy(other.data,other.data+1000000,data);
   }
   X(X&& other):
      data(other.data)
   {
      std::cout << "rcopy()" << std::endl;
      other.data=0;
   }
};

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


Цитата

сtor()
rcopy()
0xbff6727c, 0
0xbff67278, 0xb6ab0008
~dtor()
~dtor()

Автор: mes 13.4.2012, 19:55
Цитата(Sahab @  13.4.2012,  18:23 Найти цитируемый пост)
Можно ли пользоваться исходным объектом (откуда перемещали) после его перемещения?

нельзя

Цитата(Sahab @  13.4.2012,  18:23 Найти цитируемый пост)
  X x2=std::move(x1);
   x1.print();
   x2.print();

Логика проверки существования значения, путем вывода его в корне не верна.. 

Автор: boostcoder 13.4.2012, 20:16
Цитата(mes @  13.4.2012,  19:55 Найти цитируемый пост)
проверки существования значения, путем вывода его в корне не верна

кстати да.
но...раз объекта не существует, то при вызове X::print() разве не должен произойти сегфолт? или разница в том что X::print() это код, а X::data - данные? ведь по логике, код мы перемещать не можем.
так?

Автор: Sahab 13.4.2012, 20:22
Цитата(mes @  13.4.2012,  19:55 Найти цитируемый пост)
Логика проверки существования значения, путем вывода его в корне не верна.. 

Я предполагал segfault, именно это я проверял, а не вывод и его значение.

Добавлено через 38 секунд
Цитата(boostcoder @  13.4.2012,  20:16 Найти цитируемый пост)
или разница в том что X::print() это код, а X::data - данные?

Проверял и с данными, сегфолта нет.

Автор: mes 13.4.2012, 20:25
Цитата(boostcoder @  13.4.2012,  19:16 Найти цитируемый пост)
но...раз объекта не существует, то при вызове X::print() разве не должен произойти сегфолт? 

объект  (this) существует .. move не трогает сами объекты, а переносит их содержимое smile

кстати в приведенном последнем примере, print демонстриует состояние, а не использует его.. так что по сути все правильно работает smile



Автор: Sahab 13.4.2012, 20:25
Цитата(mes @  13.4.2012,  19:55 Найти цитируемый пост)
нельзя

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

Автор: mes 13.4.2012, 20:26
Цитата(Sahab @  13.4.2012,  19:22 Найти цитируемый пост)
Проверял и с данными, сегфолта нет. 

потому что ваш move-ctor обнуляет указатель на данные, и следовательно состояние объекта корректно..

Автор: Sahab 13.4.2012, 20:28
http://liveworkspace.org/code/c581e966af26dd6b8b39b963508fd5e4

Автор: mes 13.4.2012, 20:29
Цитата(Sahab @  13.4.2012,  19:25 Найти цитируемый пост)
 услышать материальное объяснение

состояние объекта после переноса неопределено.. 

Автор: Sahab 13.4.2012, 20:31
Цитата(mes @  13.4.2012,  20:26 Найти цитируемый пост)
и следовательно состояние объекта корректно..


Цитата(mes @  13.4.2012,  20:29 Найти цитируемый пост)
состояние объекта после переноса неопределено..  


Автор: mes 13.4.2012, 20:35
Код

   x1.setValue(0.3);

Вы не то проверяете.. Вы проверяете физическую сущность объекта, а move изменяет состояние..

Добавлено через 1 минуту и 9 секунд
Sahab, в Вашем случае коректно.. но такое поведение не гарантированно, а следовательно может быть и подругому .. 

Автор: boostcoder 13.4.2012, 20:50
что я понял: move перемещает данные объекта, а следовательно - состояние.
то, что после перемещения, вызов X::print() не вызывает сегфолт - говорит лишь о том, что код не перемещается. оно и логично.
при чтении X::data сегфолт не происходит потому, что X::data после перемещения все равно на что-то указывает. на мусор на стеке, к примеру.

Автор: mes 13.4.2012, 20:59
Цитата(boostcoder @  13.4.2012,  19:50 Найти цитируемый пост)
что код не перемещается. оно и логично.

код никода не перемещается.. сегфолт происходит не из за какого то перемещения кода.. 
а из за за доступа к данным за пределами разрешений.. 


Автор: boostcoder 13.4.2012, 21:07
Цитата(mes @  13.4.2012,  20:59 Найти цитируемый пост)
сегфолт происходит не из за какого то перемещения кода.

я же так и написал.

Добавлено через 4 минуты и 30 секунд
ну...почти так smile

Автор: mes 13.4.2012, 21:13
Цитата(boostcoder @  13.4.2012,  20:07 Найти цитируемый пост)
я же так и написал.
может быть.. я не понял при чем во фразе "код", поэтому и уточнил.. 

Автор: boostcoder 13.4.2012, 21:33
Цитата(mes @  13.4.2012,  21:13 Найти цитируемый пост)
я не понял при чем во фразе "код"

ну как же.. вызов функции это: 1)сохранение стека, 2)call, и т.д..
т.е. если бы перемещение так же бы и переносило и код вызова, то тогда бы точно получали сегфолт.

этим я всего лишь хотел сказать то, что успешный вызов X::print() без сегфолта - не показатель того что объект небыл перемещен. собственно, как и чтение переменной в которой до перемещения располагались данные.

Автор: mes 13.4.2012, 21:38
Цитата(boostcoder @  13.4.2012,  20:33 Найти цитируемый пост)
т.е. если бы перемещение так же бы и переносило и код вызова,

 smile, ну пусть так.. тогда вопрос .. а если не переносит код ,то сегфолт невозможен ?!


Автор: boostcoder 13.4.2012, 22:31
Цитата(mes @  13.4.2012,  21:38 Найти цитируемый пост)
а если не переносит код ,то сегфолт невозможен ?

возможен. но прежде чем получить сегфолт при доступе к "висячим" данным, нужно произвести вызов X::print(). я же об этом и говорил. а т.к. код не переносится, то и при перенесенном объекте вызов всегда будет успешным. а вот получим ли мы сегфолт при чтении данных - это уже другой вопрос.

Автор: bsa 13.4.2012, 23:13
Что вы тут спорите? move-семантика нужна в таких случаях, когда именно перемещение и необходимо. Для простых POD типов она смысла не имеет. А вот для контейнеров самое то. Потому что контейнер содержит несколько указателей. move-конструктор (например) копирует ЗНАЧЕНИЯ этих указателей в новый объект, а в старом (который передается как rvalue) их зануляет. Таким образом, деструктор старого объекта ничего не освободит, и новый объект будет существовать как ни в чем ни бывало. Это просто более быстрый вариант по сравнению с shared_ptr/array при использовании в таких ситуациях.

Автор: volatile 13.4.2012, 23:52
Цитата(boostcoder @  13.4.2012,  21:33 Найти цитируемый пост)
если бы перемещение так же бы и переносило и код вызова, то тогда бы точно получали сегфолт.

boostcoder, код вообще никогда не переносился, не переносится, и не будет переносится. 
Он один для всех объектов. 
Перенесение кода это не С++, более того, я даже не знаю, есть ли вообще в природе язык, где код переносится с экземпляром объекта.

Автор: bsa 13.4.2012, 23:58
Цитата(volatile @  14.4.2012,  00:52 Найти цитируемый пост)
Перенесение кода это не С++, более того, я даже не знаю, есть ли вообще в природе язык, где код переносится с экземпляром объекта. 

это не от языка зависит. А от программиста. Если очень захотеть, то можно это сделать. По крайней мере на платформах, где нет защиты от выполнения кода в области данных.

Автор: volatile 14.4.2012, 00:04
bsa, я имел ввиду объекто-ориентированный аспект.
само перенесение кода, конечно возможно (хотябы в обычных exe-упаковщиках)
Это другое.

Автор: boostcoder 14.4.2012, 01:10
volatile, я не говорил что код переносится. я лишь пытался прояснить это:

Цитата(mes @  13.4.2012,  19:55 Найти цитируемый пост)
Цитата(Sahab @  13.4.2012,  18:23 )
Можно ли пользоваться исходным объектом (откуда перемещали) после его перемещения?

нельзя

Цитата(Sahab @  13.4.2012,  18:23 )
  X x2=std::move(x1);
   x1.print();
   x2.print();

Логика проверки существования значения, путем вывода его в корне не верна.. 


Автор: bsa 14.4.2012, 11:16
boostcoder, исходным объектом пользоваться можно! Более того, исходный объект после перемещения используется как минимум в деструкторе. Но так как ты перенес состояние, то деструктор отработает "вхолостую" без реального освобождения ресурсов. А вот после деструктора объект уже использовать, как ты понимаешь, нельзя. По логике вещей, деструктор вызывается сразу же после отработки операции перемещения:
Код
MyClass x = y + z;
Сначала выполнится y+z и результат поместится во временный объект. Затем вызовется перемещающий конструктор для x и перенесет состояние из временного объекта. Затем будет вызван деструктор временного объекта.

Автор: mes 14.4.2012, 11:40
Цитата(bsa @  14.4.2012,  10:16 Найти цитируемый пост)
 исходным объектом пользоваться можно!

что значит можно ? да, он существуетн ( и довольно долго  если был не временным), но у него неопределено состояние, и соответсвенно, неопределено поведение..
для конкретного случая можно определить возможность использования, можно даже обратно вдохнуть жизнь в такие объекты, но нет возможности распространнить это на все случаи.. поэтому говорить о можно нельзя smile
или иногда можно, но очень осторожно smile


Автор: bsa 14.4.2012, 12:06
Цитата(mes @  14.4.2012,  12:40 Найти цитируемый пост)
у него неопределено состояние

с чего это вдруг? у него вполне определенное состояние - то, в котором его оставил "перемещатель" (например, если перемещатель занулил только указатель на начало данных вектора, а остальные оставил без изменений, то состояние неопределенное - в общем случае, только деструктор отработает корректно). А это уже задача программиста следить за тем, чтобы состояние соответствовало планам использования.
Имхо, после перемещения объект должен быть уничтожен... А "вдыхать" в него жизнь - это только делать себе хуже.

Автор: mes 14.4.2012, 12:16
Цитата(bsa @  14.4.2012,  11:06 Найти цитируемый пост)
с чего это вдруг? у него вполне определенное состояние - то, в котором его оставил "перемещатель" 

это то понятно.. но во первых нет гарантий заставляющих оставлять объект в коректном состоянии, во вторых нет (не всегда есть) такой возможности.. 

Цитата(mes @  14.4.2012,  10:40 Найти цитируемый пост)
для конкретного случая можно определить возможность использования
 а для общего случая нельзя.. 


Автор: Sahab 14.4.2012, 12:17
йопт... так можно или нельзя?
Че в стандарте написано?

Автор: mes 14.4.2012, 12:18
Цитата(bsa @  14.4.2012,  11:06 Найти цитируемый пост)
у него вполне определенное состояние - то, в котором его оставил "перемещатель" 

имелось ввиду не состояние конкретного объекта, а состояние любого объекта после перемещения..

Добавлено @ 12:20
Цитата(Sahab @  14.4.2012,  11:17 Найти цитируемый пост)
йопт... так можно или нельзя?

вообще применять move семантику нужно к rvalue...
но С++, как говорится, всегда готов придти на помощь, и можно применить move для lvalue,  однако в этом случае ответственность ложится на плечи программиста, а стандарт умывает руки  smile 

Автор: bsa 14.4.2012, 12:22
Цитата(mes @  14.4.2012,  13:18 Найти цитируемый пост)
но в С++, какк говорится, всегда готов придти на помощь, и можно применить move для lvalue, но в этом случае ответсвенность ложится на плечи программиста, а стандарт умывает руки
Классно сказано! Ёмко!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)