Re[2]: Пример по семантике переноса
От: lxa http://aliakseis.livejournal.com
Дата: 02.09.14 09:24
Оценка:
Ещё пара интересных ссылок:
Andrei Alexandrescu: Generic<Programming>: Move Constructors
chromium / chromium/src/base / master / . / move.h
Re[3]: коротко о мув семантике
От: Erop Россия  
Дата: 02.09.14 22:41
Оценка: 1 (1)
Здравствуйте, LaptevVV, Вы писали:

LVV>Тогда возникает вопрос: зачем внесли в язык то, что реализовывалось и без оного?


Что бы скомпенсировать ошибку дизайна STL...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Пример по семантике переноса
От: LaptevVV Россия  
Дата: 11.09.14 03:00
Оценка:
Сообразил, как рассказывать студентам.
1. Надо делать класс-контейнер, в котором требуется перегрузить конструктор копирования и операцию присваивания.
И обычным образом объяснить семантику значений. Ну, что-то вроде реализации вектора или дека основе динамического массива.
2. Потом возникает вопрос: а если элементами этого контейнера будут такие объекты, которые сами используют динамическую память?
Например, строки — контейнер символом в динамическом массиве.
Показать, что в семантике копирования дофига получается лишней работы по созданию-копированию-уничтожению временных объектов.
3. Показываем решение — просто переприсвоить поля-указатели.
Сами элементы не копировались-дублировались, а только необходимые управляющие поля.
Вот оно!
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: Пример по семантике переноса
От: jazzer Россия Skype: enerjazzer
Дата: 11.09.14 03:17
Оценка: +1
Здравствуйте, LaptevVV, Вы писали:

LVV>Сообразил, как рассказывать студентам.

LVV>1. Надо делать класс-контейнер, в котором требуется перегрузить конструктор копирования и операцию присваивания.
LVV>И обычным образом объяснить семантику значений. Ну, что-то вроде реализации вектора или дека основе динамического массива.
LVV>2. Потом возникает вопрос: а если элементами этого контейнера будут такие объекты, которые сами используют динамическую память?
LVV>Например, строки — контейнер символом в динамическом массиве.
LVV>Показать, что в семантике копирования дофига получается лишней работы по созданию-копированию-уничтожению временных объектов.
LVV>3. Показываем решение — просто переприсвоить поля-указатели.
LVV>Сами элементы не копировались-дублировались, а только необходимые управляющие поля.
LVV>Вот оно!

Ну то есть http://rsdn.ru/forum/cpp/5756402.1
Автор: jazzer
Дата: 26.08.14

jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: коротко о мув семантике
От: B0FEE664  
Дата: 17.09.14 13:48
Оценка: -1
Здравствуйте, Abyx, Вы писали:

LVV>>Вот что интересно.

A>а мне интересно как такая простая вещь может быть интересна.
LVV>>Мне не нужно языкового механизма, чтобы реализовать семантику перемещения в классе, управляющем памятью.
LVV>>Собственно, МастерЗив тут уже написал об этом.
LVV>>Тогда возникает вопрос: зачем внесли в язык то, что реализовывалось и без оного?
A>я уже не раз говорил — если надо знать зачем та или иная фича в C++1x — читайте proposal.

Прочита я proposal. Ну и? Мне по-прежнему не понятно, зачем нужна семантика перемещения. Вернее так: я понимаю, что с этой новой семантикой сильно сокращается необходимый объём кода. Но я так и не понял, чего нельзя сделать без её использования.

Хотите перемещать временные объекты? Ну и что этому мешает?
class RValueRefString
{
  friend class string;
  private:
    char* data;
    size_t sz;
  public:

    RValueRefString(const char* p)
    {
        sz = strlen(p) + 1;
        data = new char[sz];
        memcpy(data, p, sz);
    }

    RValueRefString(RValueRefString& r)
    {
        if ( this != &r )
        {
          delete[] data;
        
          sz = r.sz;
          data = r.data;
          r.sz = 0;
          r.data = NULL;
        }  
    }

   ~RValueRefString()
    {
        delete[] data;
    }

    RValueRefString(const string& rStr1, const string& rStr2);
};


class string
{
    friend class RValueRefString;
    char* data;

  public:

    string(const char* p)
    {
        size_t size = strlen(p) + 1;
        data = new char[size];
        memcpy(data, p, size);
    }

    ~string()
    {
        delete[] data;
    }

    string(const string& that)
    {
        size_t size = strlen(that.data) + 1;
        data = new char[size];
        memcpy(data, that.data, size);
    }

    string(RValueRefString& r)
    {
        data = r.data;
        r.sz = 0;
        r.data = NULL;
    }

    void operator = (RValueRefString& that)
    {
        delete[] data;
    
        size_t size = that.sz;
        data = new char[size];
        memcpy(data, that.data, size);
    }
    
    const char* get() const { return data; }
};


RValueRefString::RValueRefString(const string& rStr1, const string& rStr2)
{
    size_t sz1 = strlen(rStr1.data);
    size_t sz2 = strlen(rStr2.data);
    sz   = sz1 + sz2 + 1;
    data = new char[sz];
    memcpy(data,       rStr1.data, sz1);
    memcpy(data + sz1, rStr2.data, sz2 + 1);
}


RValueRefString operator + (const string& rStr1, const string& rStr2)
{
    return RValueRefString(rStr1, rStr2);
}


int main(int argc, char * argv[])
{
  string strA("abc");
  string strB("def");
  
  string strC = strA + strB;
  
  std::cout << strC.get() << std::endl;
  std::cout << "the end" << std::endl;
  
  _getch();
  return 0;
}


Почему это сделали фичей языка, а не библиотечным методом из proposal не ясно.
И каждый день — без права на ошибку...
Re[5]: коротко о мув семантике
От: Кодт Россия  
Дата: 17.09.14 13:56
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Почему это сделали фичей языка, а не библиотечным методом из proposal не ясно.


Потому что задача типовая, и удваивать сущности (auto_ptr и auto_ptr_ref) в каждом таком случае — удовольствия никакого.
Опять же,
— дефолтная реализация перемещения (то есть, копирование) доступна из коробки — не надо патчить все типы подряд
— компилятор может автоматически выводить тип ссылки из основного, и основной из ссылки; в случае с библиотеками это была бы дополнительная морока
Перекуём баги на фичи!
Re[5]: коротко о мув семантике
От: saf_e  
Дата: 17.09.14 14:21
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, Abyx, Вы писали:


LVV>>>Вот что интересно.

A>>а мне интересно как такая простая вещь может быть интересна.
LVV>>>Мне не нужно языкового механизма, чтобы реализовать семантику перемещения в классе, управляющем памятью.
LVV>>>Собственно, МастерЗив тут уже написал об этом.
LVV>>>Тогда возникает вопрос: зачем внесли в язык то, что реализовывалось и без оного?
A>>я уже не раз говорил — если надо знать зачем та или иная фича в C++1x — читайте proposal.

BFE>Прочита я proposal. Ну и? Мне по-прежнему не понятно, зачем нужна семантика перемещения. Вернее так: я понимаю, что с этой новой семантикой сильно сокращается необходимый объём кода. Но я так и не понял, чего нельзя сделать без её использования.


BFE>Почему это сделали фичей языка, а не библиотечным методом из proposal не ясно.


В вашем случае нельзя перейти от string к RValueRefString. А если это сделать получиться что-то типа shared_ptr/intrusive_ptr. Как следствие нужно внимательно жонглировать типами (не то принял/вернул потерял производительность).

Ну и теряется универсальность, вы не смоежете написать универсальный std::swap.

Опять-таки не слова о perfect-forwarding.
Re[6]: коротко о мув семантике
От: B0FEE664  
Дата: 17.09.14 14:39
Оценка:
Здравствуйте, Кодт, Вы писали:

BFE>>Почему это сделали фичей языка, а не библиотечным методом из proposal не ясно.

К>Потому что задача типовая, и удваивать сущности (auto_ptr и auto_ptr_ref) в каждом таком случае — удовольствия никакого.
Ну, может, в каждом и не надо, тем более, что, если я правильно понимаю, для POD типов оптимизации не предусмотрено.

К>Опять же,

К>- дефолтная реализация перемещения (то есть, копирование) доступна из коробки — не надо патчить все типы подряд
К>- компилятор может автоматически выводить тип ссылки из основного, и основной из ссылки; в случае с библиотеками это была бы дополнительная морока
Всё так. Только вот из proposal это не ясно. Там говорится про какие-то ужасы о невозможности:

1. One of the most important applications for move semantics is to move from temporaries (rvalues). Copy constructor elision (NRVO) almost fixes this, but not quite. Sometimes elision is not possible. Other times even when NRVO is done, it is not sufficient: alternate algorithms are desirable when the source data is known to be an rvalue (e.g. string+string example to be discussed below).
2. Moving from const objects (even rvalues) must be prohibited. It is very difficult to distinguish between a const and an rvalue in the current language (not impossible ... auto_ptr pulls it off).




Кстати, вот такой код:
string str = str1 + str2 + str3;
можно существенно ускорить отложив операции сложения до момента присваивания, чего встроенная семантика переноса не гарантирует для длинных строк. И получается, что задача так до конца и не решена.
И каждый день — без права на ошибку...
Re[5]: коротко о мув семантике
От: Abyx Россия  
Дата: 17.09.14 14:49
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Хотите перемещать временные объекты? Ну и что этому мешает?

BFE>
BFE>какой-то говнокод
BFE>


ничего что твой говнокод невалиден?
ты не можешь делать l-value референс на временный объект

судя по _getch ты используешь VC++, и значит ты там говоришь
"зачем в С++11 расширили стандарт С++03, если можно сделать то же самое на С++03, но только с расширениями стандарта С++03"?

я уже вроде писал выше, что тут вся суть в добавлении новых категорий выражений, которые позволяют безопасно биндить временные объекты к мутабельным ссылкам,
казалось бы простая штука — и всеравно люди не понимают. как так?
In Zen We Trust
Re[6]: коротко о мув семантике
От: B0FEE664  
Дата: 17.09.14 15:09
Оценка:
Здравствуйте, saf_e, Вы писали:

BFE>>Прочита я proposal. Ну и? Мне по-прежнему не понятно, зачем нужна семантика перемещения. Вернее так: я понимаю, что с этой новой семантикой сильно сокращается необходимый объём кода. Но я так и не понял, чего нельзя сделать без её использования.


_>В вашем случае нельзя перейти от string к RValueRefString. А если это сделать получиться что-то типа shared_ptr/intrusive_ptr.

Не обязательно. Можно написать аналог std::move. Дело не хитрое:
RValueRefString string::MoveToRValueRefString()
{
    RValueRefString ref;
    
    ref.data = data;
    ref.sz   = strlen(data) + 1;
    data     = NULL;
    
    return ref;
}



_>Как следствие нужно внимательно жонглировать типами (не то принял/вернул потерял производительность).


Так и с новой семантикой перемещения дела обстоят точно так же, забыл добавить оператор:
string&& operator+(string&& x, const string& y)
{
    return x += y;
}

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

_>Ну и теряется универсальность, вы не смоежете написать универсальный std::swap.

Конечно нет. Я этого и не утверждал.

_>Опять-таки не слова о perfect-forwarding.

Но ведь perfect-forwarding — не главная причина введения семантики перемещения?
И каждый день — без права на ошибку...
Re[7]: коротко о мув семантике
От: Кодт Россия  
Дата: 17.09.14 15:10
Оценка: +1
Здравствуйте, B0FEE664, Вы писали:

BFE>Кстати, вот такой код:

BFE>string str = str1 + str2 + str3;
BFE>можно существенно ускорить отложив операции сложения до момента присваивания, чего встроенная семантика переноса не гарантирует для длинных строк. И получается, что задача так до конца и не решена.

Этак мы до хаскелла и идриса доберёмся, с их формальными преобразованиями программ.

Существенное ускорение там можно сделать в три этапа:
— приведение к acc += str1; acc += str2; acc += str3; str = move(acc);
— приведение к len = str1.size()+str2.size()+str3.size(); acc.reserve(len); ...
— полная ленивость: если нет str =, то остаться в виде expression template
Перекуём баги на фичи!
Re[7]: коротко о мув семантике
От: saf_e  
Дата: 17.09.14 15:13
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, saf_e, Вы писали:


BFE>>>Прочита я proposal. Ну и? Мне по-прежнему не понятно, зачем нужна семантика перемещения. Вернее так: я понимаю, что с этой новой семантикой сильно сокращается необходимый объём кода. Но я так и не понял, чего нельзя сделать без её использования.


_>>Как следствие нужно внимательно жонглировать типами (не то принял/вернул потерял производительность).


BFE>Так и с новой семантикой перемещения дела обстоят точно так же, забыл добавить оператор:

BFE>
BFE>string&& operator+(string&& x, const string& y)
BFE>{
BFE>    return x += y;
BFE>}
BFE>

BFE>потерял в производительности.

Ну, тип становится всего один, и при возврате не нужно писать &&

_>>Ну и теряется универсальность, вы не смоежете написать универсальный std::swap.

BFE>Конечно нет. Я этого и не утверждал.

_>>Опять-таки не слова о perfect-forwarding.

BFE>Но ведь perfect-forwarding — не главная причина введения семантики перемещения?

Ну, собственно, к чему веду и я и все остальные. Фича нужная и позволяет меньшими усилиями писать производительный код там, где раньше это было или тяжело или невозможно.
Re[6]: коротко о мув семантике
От: B0FEE664  
Дата: 17.09.14 15:32
Оценка:
Здравствуйте, Abyx, Вы писали:

BFE>>Хотите перемещать временные объекты? Ну и что этому мешает?

BFE>>
BFE>>какой-то говнокод
BFE>>

A>ничего что твой говнокод невалиден?
Где?

A>ты не можешь делать l-value референс на временный объект

И какое отношение это имеет к коду?

A>судя по _getch ты используешь VC++, и значит ты там говоришь

я много чего использую.

A>"зачем в С++11 расширили стандарт С++03, если можно сделать то же самое на С++03, но только с расширениями стандарта С++03"?

Нет. Я говорю, что отсыл на proposal не является ответом на вопрос Лаптева.

A>я уже вроде писал выше, что тут вся суть в добавлении новых категорий выражений, которые позволяют безопасно биндить временные объекты к мутабельным ссылкам,

Т.е. всё сводится к удобству и безопасности, а ни о какой новой функциональности речи не идёт?

A>казалось бы простая штука — и всеравно люди не понимают. как так?

Чего именно я не понимаю?
И каждый день — без права на ошибку...
Re[8]: коротко о мув семантике
От: B0FEE664  
Дата: 17.09.14 15:43
Оценка:
Здравствуйте, saf_e, Вы писали:

BFE>>>>Прочита я proposal. Ну и? Мне по-прежнему не понятно, зачем нужна семантика перемещения. Вернее так: я понимаю, что с этой новой семантикой сильно сокращается необходимый объём кода. Но я так и не понял, чего нельзя сделать без её использования.


_>>>Как следствие нужно внимательно жонглировать типами (не то принял/вернул потерял производительность).

BFE>>Так и с новой семантикой перемещения дела обстоят точно так же, забыл добавить оператор:
BFE>>
BFE>>string&& operator+(string&& x, const string& y)
BFE>>{
BFE>>    return x += y;
BFE>>}
BFE>>

BFE>>потерял в производительности.
_>Ну, тип становится всего один, и при возврате не нужно писать &&
В данном операторе наличие && у возвращаемого типа обеспечивает рост производительности
И каждый день — без права на ошибку...
Re[7]: коротко о мув семантике
От: Abyx Россия  
Дата: 17.09.14 16:54
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, Abyx, Вы писали:


BFE>>>Хотите перемещать временные объекты? Ну и что этому мешает?

BFE>>>
BFE>>>какой-то говнокод
BFE>>>

A>>ничего что твой говнокод невалиден?
BFE>Где?
в компиляторе. твой код не компилируется.

A>>ты не можешь делать l-value референс на временный объект

BFE>И какое отношение это имеет к коду?
да, у тебя временный объект (результат op+) передается в конструктор RValueRefString(RValueRefString& r)
это не валидный С++, и компилируется только за счет расширений VC++

A>>я уже вроде писал выше, что тут вся суть в добавлении новых категорий выражений, которые позволяют безопасно биндить временные объекты к мутабельным ссылкам,

BFE>Т.е. всё сводится к удобству и безопасности, а ни о какой новой функциональности речи не идёт?
давай ты сначала напишешь свой код так чтобы он компилировался строго согласно С++03, а потом обсудим это еще раз.
рекомендую этот онлайн-компилятор — http://coliru.stacked-crooked.com/a/30fcce2f2edbf1cb
In Zen We Trust
Re[2]: Пример по семантике переноса
От: Erop Россия  
Дата: 17.09.14 18:26
Оценка: 1 (1) +1
Здравствуйте, LaptevVV, Вы писали:

LVV>Вот оно!


Всё круче! Можно, например, сделать массив потоков, пооткрывать их все прямо внутри массива, а потом массив заресайзить...
То есть можно двигать вообще некопируемые в принципе объекты,..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Пример по семантике переноса
От: vpchelko  
Дата: 17.09.14 21:30
Оценка:
Здравствуйте, LaptevVV, Вы писали:

Опять мешаете перенос, копирование и присваивание. Каша. Опять же вижу выше по ссылкам, где "move" называют присваивание с копированием
int m=7, n=0;
n=m; //"move" m to n.

... плохой пример, мешает пониманию.
Сало Украине, Героям Сала
Отредактировано 17.09.2014 21:58 vpchelko . Предыдущая версия . Еще …
Отредактировано 17.09.2014 21:56 vpchelko . Предыдущая версия .
Отредактировано 17.09.2014 21:49 vpchelko . Предыдущая версия .
Отредактировано 17.09.2014 21:45 vpchelko . Предыдущая версия .
Отредактировано 17.09.2014 21:31 vpchelko . Предыдущая версия .
Re[8]: коротко о мув семантике
От: B0FEE664  
Дата: 18.09.14 10:56
Оценка:
Здравствуйте, Abyx, Вы писали:

A>>>ты не можешь делать l-value референс на временный объект

BFE>>И какое отношение это имеет к коду?
A>да, у тебя временный объект (результат op+) передается в конструктор RValueRefString(RValueRefString& r)
A>это не валидный С++, и компилируется только за счет расширений VC++

О! Теперь я понял о чём речь. Я всё время забываю, что в стандарте есть этот прямой запрет.
И каждый день — без права на ошибку...
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.