Constantine
собственно конструктор перемещения
Ivan
Так, а для чего && в аргументе функции, если мне всё равно std::move(str) в клиентском коде приходится писать
Constantine
для того, чтобы различать
Constantine
если тебе это нужно
Constantine
например, конструктор перемещения string(string&&) не может быть определен без &&
Ivan
в функцию можно что-то замувить без std::move(obj) в клиентском коде?
Constantine
по-нормальному нет
Constantine
reinterpret_cast, думаю, сработает
Constantine
ах да
Constantine
временный объект всегда перемещается
Constantine
foo(string("hello")) будет конструктор string(const char*) и потом string(string&&) перемещение
Constantine
если void foo(string s)
Constantine
преобразование string& в string&& компилятором выполнено не будет
Constantine
т.е.
void foo(string &&s);
//client
string s;
foo(s); //CE
Ivan
ошибка компиляции будет
Constantine
CE это как раз compilation error
Ivan
я тебя понял
Ivan
но не хотелось бы писать std::move(s) ради этого
Constantine
если хочешь понять механику перемещения, поработай с std::unique_ptr
Constantine
собственно это потребитель номер 1
Constantine
и характерный пример MoveConstructible но не CopyConstructible класса
Ivan
это я понимаю
Ivan
но мне нужно реально мувить
Constantine
?
Constantine
хочешь РАЗРУШАТЬ?
Ivan
в смысле, я знаю что у unique_ptr запрещено копирование
Ivan
ДА!
🐙 Antony
Constantine
ну делай swap с временным объектом
Ivan
оверхед
Constantine
лучший способ разрушения
Constantine
да то же самое
Constantine
swap это три мува
Александр
Dmitry
кстати, у Qt в семантике перемещения - свапится, у std:: источник обнуляется. фишка такая)
Александр
свапится у всех, просто у некоторых чистится источник потом
Constantine
?
Constantine
в конструкторе свопы писать?
Dmitry
🐙 Antony
кстати, всегда было интересно, с чем это связано
Это связано с безопасностью. Если разрешать временные объекты передавать по обычной ссылке, тогда будет вот так:
long l = 1;
foo(int& i) { ++i; }
...
foo(l);
assert(l == 2); // oops, l ==1
Constantine
оО а где здесь временный объект
Александр
тоже не понял
Александр
а, ну да
Александр
логично, спасибо
Ivan
@antoshkka http://cpp.sh/4pkwz
Constantine
вообще я не очень понимаю, как положено здесь по стандарту
Constantine
потому что VS разрешает
Constantine
void f(std::string &x){}
void g(){ f(std::string("hello")); }
Constantine
но дает варнинг на макслевеле
Constantine
т.е. разрешено неявное преобразование string&& в string&
Constantine
без промежуточных
Constantine
f("hello"); //CE
🐙 Antony
Он больше в стиле Ranges чем в стиле текущих <algorithm>. Его надо будет протащить, но прям сейчас это не получится
🦥Alex Fails
Dmitry
да все тайп трайтсы криво названы)
Крылатый
Вангую ради лулзов.
🦥Alex Fails
У майерса было вроде б ппочему
Крылатый
Расширениями вообще не стоит пользоваться.
🐙 Antony
void foo(std::string&& s) {
std::string tmp = std::move(s); //не будет ли здесь оверхеда при создании новой строки?
std::cout << tmp << " 1\n";
}
Чтобы гарантированно без всякого overheada
void foo(std::string&& s) {
std::cout << s << " 1\n";
s.clear();
}
Крылатый
Если не хаскель, конечно.
🐙 Antony
Constantine
Constantine
если предполагается (конвенцией), что эта ссылка может быть сохранена, то такое преобразование - ошибка
Constantine
я в свое время не придумал, как в стандарте C++98 не делать лишнюю перегрузку вызова с неконстантным функтором, поэтому пользовался ради параметра по умолчанию в таких случаях
🦥Alex Fails
Constantine
на 2003 вижаке я не уверен, что это вообще работало :)
Constantine
ему лучше было вопросы посложнее не задавать
Constantine
в любом случае это сейчас не нужно, я могу лямбдой функторы писать и внутри ссылку ставить, так что просто всегда по значению такой функтор получаю
Dmitry
...
Dmitry
а динамического полиморфизма на статике сейчас модного не завезли?
Constantine
что вы имеете в виду?
Dmitry
вопрос на libastral рассчитан)
Dmitry
но это ладно
🦥Alex Fails
Динамический полиморфизм - это виртуальные функции
🦥Alex Fails
Статический - это цртп
Dmitry
ага
Dmitry
всё так