Re[12]: swap move forward
От: rg45 СССР  
Дата: 14.03.13 15:25
Оценка:
Здравствуйте, uzhas, Вы писали:

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


U>>в этом случае мне непринципиально std::forward или std::move использовать. лишь бы перемещалось


U>на самом деле они работают по-разному, нужен именно std::move

U>хватит меня запутывать!

Работают, возможно, они по-разному, только приводят к одному и тому же результату. Посмотри в стандарт:

std::move

template <class T> typename remove_reference<T>::type&& move(T&& t) noexcept;

Returns: static_cast<typename remove_reference<T>::type&&>(t).


std::forward:

template <class T> T&& forward(typename remove_reference<T>::type& t) noexcept;
template <class T> T&& forward(typename remove_reference<T>::type&& t) noexcept;

2 Returns: static_cast<T&&>(t).

--
Справедливость выше закона. А человечность выше справедливости.
Re[17]: to uzhas
От: Evgeny.Panasyuk Россия  
Дата: 14.03.13 15:25
Оценка:
Здравствуйте, uzhas, Вы писали:

R>>std::forward тоже всегда возвращает rvref:

U>по ссылкам, что я ранее уже дал можно найти следующее
U>

U>C++11, by contrast, introduces the following reference collapsing rules:
U>A& & becomes A&
U>A& && becomes A&
U>A&& & becomes A&
U>A&& && becomes A&&

Да именно, я запомнил эту табличку как "lvalue reference infection" (по-моему её так Stephan T. Lavavej назвал).
Re[13]: swap move forward
От: Evgeny.Panasyuk Россия  
Дата: 14.03.13 15:29
Оценка:
Здравствуйте, rg45, Вы писали:

R>Работают, возможно, они по-разному, только приводят к одному и тому же результату. Посмотри в стандарт:


R>1 Returns: static_cast<typename remove_reference<T>::type&&>(t).


R>2 Returns: static_cast<T&&>(t).


Это семантически разные результаты. Первое — всегда rvref.
Второе rvref только если is_same<T,typename remove_reference<T>::type> или is_rvalue_reference<T>.
Re[8]: to uzhas
От: Константин Россия  
Дата: 14.03.13 15:40
Оценка: +1
Здравствуйте, rg45, Вы писали:

EP>>>А как же C++11 std::swap в конце концов?

EP>>> T c(std::move(a)); a=std::move(b); b=std::move(c);

R>>swap можно можно реализовать при помощи std::forward:

R>> T c(std::forward<T>(a)); a=std::forward<T>(b); b=std::forward<T>(c);

Не знаю, работоспособен ли пример с std::forward, надеюсь, что будет Лично для меня намного читабельней и понятней вариант с std::move. Вариант с std::forward вызывает дискомфорт и недоверие.
Re[13]: to uzhas
От: rg45 СССР  
Дата: 14.03.13 15:50
Оценка:
Здравствуйте, uzhas, Вы писали:

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

R>>Есть что возразить?

U>я не понимаю что ты хочешь доказать?

U>тебе не нравится только название std::move? или сама возможность перетаскивать объекты?

Как мне кажется я достаточно ясно сформулировал свою мысль: http://rsdn.ru/forum/cpp/5099696.1
Автор: rg45
Дата: 14.03.13
. Я не имел намерений что-либо доказывать, я выразил сомнение, в надежде, что вы либо согласитесь со мной, либо переубедите меня. Спорить я был вынужден вовсе не потому, что я уперся рогом и не хочу сдвинуться с места, а потому, что большинство возражений, которые я услышал были сформированы на уровне подсознания и эмоций, а некоторые просто ошибочными. Я с радостью изменю свою точку зрения, как только услышу внятное объяснение.
--
Справедливость выше закона. А человечность выше справедливости.
Re[14]: to uzhas
От: uzhas Ниоткуда  
Дата: 14.03.13 15:55
Оценка:
Здравствуйте, rg45, Вы писали:

R>Как мне кажется я достаточно ясно сформулировал свою мысль: http://rsdn.ru/forum/cpp/5099696.1
Автор: rg45
Дата: 14.03.13
.

мысль плохо сформулирована и не прослеживается связь с std::forward, уточни плиз что ты пытаешься доказать своей реализацией swap<T>
и лучше не использовать выражения без четкого определения типа "идеальная архитектура" или "зло", потому что это лишь мешает тебя понять
Re[17]: to uzhas
От: rg45 СССР  
Дата: 14.03.13 16:01
Оценка: -1
Здравствуйте, uzhas, Вы писали:

R>>std::forward тоже всегда возвращает rvref:


U>по ссылкам, что я ранее уже дал можно найти следующее

U>

U>C++11, by contrast, introduces the following reference collapsing rules:
U>A& & becomes A&
U>A& && becomes A&
U>A&& & becomes A&
U>A&& && becomes A&&


Табличка, красивая, жаль только, она слабо коррелирует и со стандартом и с практикой:

http://liveworkspace.org/code/1ykoSY$1

20.2.3/2

template <class T> T&& forward(typename remove_reference<T>::type& t) noexcept;
template <class T> T&& forward(typename remove_reference<T>::type&& t) noexcept;

2 Returns: static_cast<T&&>(t).

--
Справедливость выше закона. А человечность выше справедливости.
Re[15]: to uzhas
От: rg45 СССР  
Дата: 14.03.13 16:05
Оценка:
Здравствуйте, uzhas, Вы писали:

R>>Как мне кажется я достаточно ясно сформулировал свою мысль: http://rsdn.ru/forum/cpp/5099696.1
Автор: rg45
Дата: 14.03.13
.

U>мысль плохо сформулирована и не прослеживается связь с std::forward, уточни плиз что ты пытаешься доказать своей реализацией swap<T>
U>и лучше не использовать выражения без четкого определения типа "идеальная архитектура" или "зло", потому что это лишь мешает тебя понять

Мы два круга уже пробежали, идти на третий уже не охота.
--
Справедливость выше закона. А человечность выше справедливости.
Re[18]: to uzhas
От: Evgeny.Panasyuk Россия  
Дата: 14.03.13 16:08
Оценка:
Здравствуйте, rg45, Вы писали:

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


Всё в порядке:
#include <utility>

struct A
{
   A() { }
   A(A&&) { }
   
   A(const A&) = delete;
   A& operator=(const A&) = delete;
};

template<typename T>
void forwarding(T &&t)
{
   A(std::forward<T>(t));
}

int main()
{
   A first;
   //forwarding(std::move(first));
   forwarding(first);
}

Compilation finished with errors:
source.cpp: In instantiation of 'void forwarding(T&&) [b]with T = A&[/b]]':
source.cpp:22:20: required from here
source.cpp:15:4: error: use of deleted function 'A::A(const A&)'
source.cpp:8:4: error: declared here

Re[9]: to uzhas
От: rg45 СССР  
Дата: 14.03.13 16:10
Оценка:
Здравствуйте, Константин, Вы писали:

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


EP>>>>А как же C++11 std::swap в конце концов?

EP>>>> T c(std::move(a)); a=std::move(b); b=std::move(c);

R>>>swap можно можно реализовать при помощи std::forward:

R>>> T c(std::forward<T>(a)); a=std::forward<T>(b); b=std::forward<T>(c);

К>Не знаю, работоспособен ли пример с std::forward, надеюсь, что будет


Пример работоспособен, в этом топике уже достаточное количество ссылок на разные его вариации.

К>Лично для меня намного читабельней и понятней вариант с std::move. Вариант с std::forward вызывает дискомфорт и недоверие.


Это странно слышать, учитывая то, std::move не соответствует своему названию — она ничего не перемещает, и ничего кроме static_cast не делает.
--
Справедливость выше закона. А человечность выше справедливости.
Re[10]: to uzhas
От: uzhas Ниоткуда  
Дата: 14.03.13 16:26
Оценка:
Здравствуйте, rg45, Вы писали:

R>Это странно слышать, учитывая то, std::move не соответствует своему названию — она ничего не перемещает, и ничего кроме static_cast не делает.

какое название ты бы предложил?
Re[11]: to uzhas
От: rg45 СССР  
Дата: 14.03.13 16:27
Оценка:
Здравствуйте, uzhas, Вы писали:

R>>Это странно слышать, учитывая то, std::move не соответствует своему названию — она ничего не перемещает, и ничего кроме static_cast не делает.

U>какое название ты бы предложил?

Я уже боюсь предлагать что-либо
--
Справедливость выше закона. А человечность выше справедливости.
Re[10]: to uzhas
От: Константин Россия  
Дата: 14.03.13 16:31
Оценка:
Здравствуйте, rg45, Вы писали:


К>>Лично для меня намного читабельней и понятней вариант с std::move. Вариант с std::forward вызывает дискомфорт и недоверие.

R>Это странно слышать, учитывая то, std::move не соответствует своему названию — она ничего не перемещает, и ничего кроме static_cast не делает.

Для меня std::move хороший способ задокументировать следующее:
— текущее состояние нам не нужно, и может быть перемещено
— мы отдаём себе отчёт, что объект после этого может содержать какое-то другое (но валидное) состояние
— те кто могут, радостно воспользуются возможностью стащить ресурс

std::forward я пока спинным мозгом не чувствую

Пример, когда std::move может быть полезен — атомарное изменение выходного параметра.
bool getSomeData( ..., A& out )
{
  A ret;

  //
  // construct, update A
  // ...
  // may throw, or return false
  //

  // out is updated in atomic manner, if everything else is ok
  // c++03 analog is out.swap(ret); if there is A::swap(...)

  out = std::move(ret);
  return true;
}
Re[12]: to uzhas
От: uzhas Ниоткуда  
Дата: 14.03.13 16:33
Оценка:
Здравствуйте, rg45, Вы писали:

R>Я уже боюсь предлагать что-либо

std::move ничего не перемещает, однако если вдуматься, то связь с перемещением все же есть: функция подготавливает объект к перемещению, делает так, чтобы компилятор начал эту операцию
а если еще и использовать rvalue ref именно для перемещения (не опционального, о чем я выше писал), то и две операции сольются вместе : подготовка к перемещению и само перемещение
Re[12]: to uzhas
От: Константин Россия  
Дата: 14.03.13 16:47
Оценка: +1 :)
Здравствуйте, rg45, Вы писали:

U>>какое название ты бы предложил?


R>Я уже боюсь предлагать что-либо


Изверги, нельзя же так с людьми обращаться
Re[13]: to uzhas
От: rg45 СССР  
Дата: 14.03.13 16:47
Оценка:
Здравствуйте, uzhas, Вы писали:

U>std::move ничего не перемещает, однако если вдуматься, то связь с перемещением все же есть: функция подготавливает объект к перемещению, делает так, чтобы компилятор начал эту операцию

U>а если еще и использовать rvalue ref именно для перемещения (не опционального, о чем я выше писал), то и две операции сольются вместе : подготовка к перемещению и само перемещение

В таком случае более подходящим названием было бы prepare_to_move или как-то так. Но как по мне, весь этот "ансамбль" move/forward выглядит криво, и не плохо было бы, если бы его полностью пересмотрели.
--
Справедливость выше закона. А человечность выше справедливости.
Re[11]: to uzhas
От: Evgeny.Panasyuk Россия  
Дата: 14.03.13 17:02
Оценка: 6 (1)
Здравствуйте, Константин, Вы писали:

К>Для меня std::move хороший способ задокументировать следующее:

К>- текущее состояние нам не нужно, и может быть перемещено
К>- мы отдаём себе отчёт, что объект после этого может содержать какое-то другое (но валидное) состояние
К>- те кто могут, радостно воспользуются возможностью стащить ресурс

Это я пытался показать здесь
Автор: Evgeny.Panasyuk
Дата: 14.03.13
.
Пример в котором делается std::move, но никто ресурсы "не тащит" — никак не противоречит описанным выше пунктам.

К>std::forward я пока спинным мозгом не чувствую


Он нужен для perfect forwarding. Допустим нужно принять аргументы, неважно какие, и передать их в неизменном виде в другую функцию (если было rvalue, то нужно передать rvalue (не забыв про move)). Например это фабрика, которой нужно передать аргументы в конструктор.
Здесь всё подробно.
Re[14]: to uzhas
От: Evgeny.Panasyuk Россия  
Дата: 14.03.13 17:08
Оценка:
Здравствуйте, rg45, Вы писали:

R>Но как по мне, весь этот "ансамбль" move/forward выглядит криво, и не плохо было бы, если бы его полностью пересмотрели.


Что именно "криво"? Какие конкретно места не нравятся?
Re[19]: to uzhas
От: rg45 СССР  
Дата: 14.03.13 17:41
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

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


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


EP>Всё в порядке:

EP>
  Скрытый текст
EP>#include <utility>

EP>struct A
EP>{
EP>   A() { }
EP>   A(A&&) { }
   
EP>   A(const A&) = delete;
EP>   A& operator=(const A&) = delete;
EP>};

EP>template<typename T>
EP>void forwarding(T &&t)
EP>{
EP>   A(std::forward<T>(t));
EP>}

EP>int main()
EP>{
EP>   A first;
EP>   //forwarding(std::move(first));
EP>   forwarding(first);
EP>}
EP>

EP>

EP>Compilation finished with errors:
EP>source.cpp: In instantiation of 'void forwarding(T&&) [b]with T = A&[/b]]':
EP>source.cpp:22:20: required from here
EP>source.cpp:15:4: error: use of deleted function 'A::A(const A&)'
EP>source.cpp:8:4: error: declared here



http://liveworkspace.org/code/OImmo$5

Ну где ж в порядке-то?
--
Справедливость выше закона. А человечность выше справедливости.
Re[15]: to uzhas
От: rg45 СССР  
Дата: 14.03.13 17:44
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

R>>Но как по мне, весь этот "ансамбль" move/forward выглядит криво, и не плохо было бы, если бы его полностью пересмотрели.


EP>Что именно "криво"? Какие конкретно места не нравятся?


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

  1. http://liveworkspace.org/code/1ykoSY$1
  2. http://liveworkspace.org/code/OImmo$5
--
Справедливость выше закона. А человечность выше справедливости.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.