LINUX.ORG.RU

в чем проблема загуглить ? +10500 раз обсуждалось и объяснялось на многих интернет ресурсах

anonymous
()

move - каст obj к && всегда, forward только тогда, условно, если obj уже &&. Это работает совместно с универсальными ссылками. Что гуглить понятно.

mamos3
()
Ответ на: комментарий от Lzzz

Есть тонкие нюансы, которые хочу прояснить.

Так спрашивай про нюансы, а не про «В чем разница между std::move|forward?»

Например что такое perfect forwarding

Это не «тонкий нюанс», фгугл.

anonymous
()
Ответ на: комментарий от Lzzz

то есть вы уже их ищете для посмотреть и обучиться по нормальному С++ а не дергая отдельные знания ?

anonymous
()
Ответ на: комментарий от Lzzz

https://eli.thegreenplace.net/2014/perfect-forwarding-and-universal-references-in-c

https://en.cppreference.com/w/cpp/utility/forward

https://habr.com/ru/post/242639/

Perfect forwarding на пальцах — это когда ты пишешь шаблонную функцию-обёртку, в которую может прийти объект произвольного типа, и тебе нужно передать этот объект дальше, полностью сохранив его тип и ссылочную категорию (если тебе передали T &, то нужно вызвать вложенную функцию от T &, если передали T && — то нужно вызвать вложенную функцию от T &&). Отсюда perfect.

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 3)
Ответ на: комментарий от mamos3

А точему тогда говорят, что forward нужен для передачи информации о типе? move теряет эту информацию?

Lzzz
() автор топика
Ответ на: комментарий от Lzzz

А точему тогда говорят, что forward нужен для передачи информации о типе?

Правильно говорят.

move теряет эту информацию?

Да, move всегда возвращает T &&, даже если на вход подать например T &.

intelfx ★★★★★
()
Ответ на: комментарий от Lzzz

зачем вам знать что и зачем говорят если С++ вы изучать не хотите

а что и зачем, следует из базовых знаний которым вы явно не владеете

anonymous
()
Ответ на: комментарий от intelfx

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

Lzzz
() автор топика
Ответ на: комментарий от intelfx

потому что ей нужно учить весь язык а не выдернутые знания-термины-семантику

anonymous
()
Ответ на: комментарий от anonymous

А ты наверно владеешь? Тогда ответь почему компилятор сам не может вывести по типу объекта когда нужно делать копирование, а когда перемещение?

Lzzz
() автор топика
Ответ на: комментарий от Lzzz

я владею но терять время на объяснения и обучению вас языку С++ не хочу

хотеть изучать и тратить время на само обучение а не на отнимание времени у других должны хотеть ВЫ

anonymous
()
Ответ на: комментарий от Lzzz

Потому что не нужно слушать идиотов. Вернее кто-то, возможно, даже говорил что-то вменяемое, но в момент передачи что-то поломалось.

Никакой передачи, никакой forward не нужен и никакой move тут вообще не причём. И никакой move ничего не теряет.

Условно, для птушников. macdak << lzzz - это move в макдак, а вот это форвард if(!zachetka) macdak << lzzz. Соответственно, move тебя сразу в макдак отправит, а forward посмотрит зачётку. Это просто две разные операции с разной семантикой. Общее в них то, что move является составной частью forward, но никак не означает, что move что-то там теряет.

Но не особо видно, что forward тебе нужен. Поэтому можно забить. move - это будущие.

mamos3
()
Ответ на: комментарий от anonymous
template <class T>
A(T&& aName) : name(aName) {}

A(string & aName) делаешь копирование, A(string && aName) - перемещение. Все. 
Lzzz
() автор топика
Ответ на: комментарий от Lzzz

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

Очевидно, что в ситуации:

T r = 123;

auto && r1 = r;
// Здесь r == 0

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

А вот если на него ссылка есть - ты не хочешь терять в нём данные.

mamos3
()
Ответ на: комментарий от mamos3

move - это будущие

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

anonymous
()
Ответ на: комментарий от mamos3

Передача аргумента, условно, ничем не отличается от присваивания.

🤦‍♂️

anonymous
()
Ответ на: комментарий от mamos3

Я понимаю что базовая семантика, вопрос почему компилятор не может их различить и нужен костыль в ввиде std::forward?

Lzzz
() автор топика
Ответ на: комментарий от anonymous

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

линейных типов Это говно.

А смысл моего цитаты в следующем. Операция move опеределана как перемещение пациента в макдак, за кассу. А далее определена как будущие.

mamos3
()
Ответ на: комментарий от mamos3

Операция move опеределана как перемещение пациента

А вдруг почкованием/клонированием.

anonymous
()
Ответ на: комментарий от mamos3

СМ. мой пример выше. Он должен отличить при инстанцировании шаблона string & от string && и для первого сделать копирование, а для второго перемещение, что тебе непонятно?

Lzzz
() автор топика
Ответ на: комментарий от Lzzz

для первого сделать копирование, а для второго перемещение

Стандарт говорит что не должен.

anonymous
()
Ответ на: комментарий от Lzzz

Я даже тебе отвечу, попытавшись твои потуги свести к чему-то минимально-вменяемому.

Действительно, forward можно выкинуть добавив возможности к языку, но, опять же, это нужно в любом случае что-то сделать - самом оно работать в принципе не может.

И вот уже проблема C++. В С++(и особенно в других языках) нету нормальных функций, нету семантического инлайна(который и решает в том числе эту проблему).

И никогда эта проблема не будет решена ни в С++, ни в других языках.

mamos3
()
Ответ на: комментарий от Lzzz

А что будет, если сделать move для string &?

У тебя будет xvalue типа string, обозначающее тот же объект, что и аргумент.

anonymous
()
Ответ на: комментарий от Lzzz

Во-первых я не обязан следить за твоими потоками шизофазии, а во-вторых - это полная чушь. Пример дерьмо и ничего не показывает. Сообщи для начала - что он должен мне сообщить. Что из него следует?

И да, осиль C++ и нормальный стиль. Читать бездарный мусор мне противно.

mamos3
()
Ответ на: комментарий от mamos3

И никогда эта проблема не будет решена ни в С++, ни в других языках

А теперь представь себя на зачете. Ты нормально объяснить можешь? Например, нельзя будет скомпилировать старые программы, или что то еще?

Lzzz
() автор топика
Ответ на: комментарий от Lzzz

А теперь представь себя на зачете.

Зачем? Это для тебя они - хозяева. Для меня они - птушники.

Например, нельзя будет скомпилировать старые программы, или что то еще?

Нет, причём тут старые программы? У тебя плохо с логикой. Существуют языки для которых нет старых программ.

Значит причина где-то на фундаментальном уровне. Объяснить её птушнику - не представляется возможным. Просто запомни это. Там, где есть функции - такого поведения нет и быть не может.

mamos3
()
Ответ на: комментарий от Lzzz

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

anonymous
()
Ответ на: комментарий от mamos3

Nick: mamos3 ID: 178646

Дата регистрации: 15.06.20 07:16:34 Последнее посещение: 16.06.20 15:15:23 Статус: анонимный

очередной забаненый и воскресший царек живущий всю жизнь на лоре

и не написавший ни одной С++ программы за эту самую жизнь

anonymous
()
Ответ на: комментарий от Lzzz

Ты не думал - почему forward в С++ выглядит как говно? Зачем туда тип? Правильно, потому что функции говно.

В общем, ради пацанов даже объясню. https://godbolt.org/z/AdVVXe - вот «функции» с семантическим инлайном. Если попроще, то это что-то типа макросов.

И здесь ты можешь реализовать ИСТИННЫЙ pf(в крестах он фейковый, на самом деле. А в других недоязычках его вообще нет). Так же можешь реализовать forward, который невозможно реализовать на С++ без костылей.

mamos3
()
Ответ на: комментарий от mamos3

А что это?

Шаблон. Ещё других поучать берёшься.

anonymous
()
Ответ на: комментарий от mamos3

Это я тебя спросила, что такое std::forward? Функция или шаблон?

Lzzz
() автор топика

Вандевурд, Дэвид, Джосаттис, Николаи М., Грегор, Дуглас. Шаблоны C++. Справочник разработчика, 2-е изд Глава 6. Тут лучше читать.

rumgot ★★★★★
()

А царь-то ненастоящий! Расходимся.

anonymous
()
Ответ на: комментарий от Lzzz
void overloaded (const string& x) {}
void overloaded (string&& x) {}

// function template taking rvalue reference to deduced type:
template <class T> void fn (T&& x) {
  overloaded (x); // #1
  overloaded (std::forward<T>(x)); // #2
}

int main () {
  string s;
  fn(move(s));
}

После второго вызова overloaded() строка x будет мусором, мы хотим забрать у неё ресурс самым последним этапом, перед этим будем как-то пользоваться её, куда-то передавать, а под конец «грохним». Для этого и нужен «костыль» std::forward - выбрать этот момент (но лишь тогда, когда fn попало rvalue). Естественно, компилятор не знает чего ты там задумала. Ну и да, один общий код для rvalue/lvalue.

pavlick ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.