С одной стороны на практике оказалось, что мув и не нужен в большинстве случаев.
Но с другой стороны....интересно, ему самому не кажется это говнокодом?
Когда нужно учитывать/держать в голове неявные вещи чуть ли не на каждом шагу — это же 100% признак говнокода/говноархитектуры.
В принципе, все верно, только в перdой перегрузке std::is_rvalue_reference_v<Collection&> всегда будет вычисляться в false (с логическим отрицанием соответственно всегда будет true), поэтому SFINAE здесь просто не дает никакого эффекта и можно упростить до:
Здравствуйте, sergii.p, Вы писали:
SP>Здравствуйте, B0FEE664, Вы писали:
SP>оно конечно работает. Но теперь я ничего не понимаю Почему условия разные? Они получается не покрывают 100% случаев?
Тут фокус в том, что, поскольку Collection — шаблонный параметр, Collection&& — это особый вид ссылки, называемый forwarding reference. Эти ссылки "всеядны" в том смысле, что могут сопоставляться не только с rvalue ссылками, но и с lvalue. Благодаря своей всеядности функции с такими ссылками в параметрах способны выигрывать подстановку там, где это не ожидается. Для того, чтобы вторая прегрузка использовалась только для rvalue выкфжений, подстановку lvalue выражений нужно блокировать при помощи SFINAE, как показал B0FEE664.
Здравствуйте, sergii.p, Вы писали:
SP>оно конечно работает. Но теперь я ничего не понимаю Почему условия разные? Они получается не покрывают 100% случаев?
Я подправил твой пример, чтоб работало так, как ты хочешь. Это не самый рациональный способ, зато он поможет тебе быстрее понять, как работают forwarding references.
Здравствуйте, _NN_, Вы писали:
_NN>Если нужно rvalue следует добавить const:
После чего модификация объекта становится недоступной. В то время как главной мотивацией для появления rvalue ссылок было как раз то, что далеко не всегда rvalue автоматом означает константность.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, _NN_, Вы писали:
_NN>>Если нужно rvalue следует добавить const:
R>После чего модификация объекта становится недоступной. В то время как главной мотивацией для появления rvalue ссылок было как раз то, что далеко не всегда rvalue автоматом означает константность.
Ну тут надо исходить из задачи.
В данном выше примере изменений объекта не было.
Здравствуйте, sergii.p, Вы писали:
SP>оно конечно работает. Но теперь я ничего не понимаю Почему условия разные? Они получается не покрывают 100% случаев?
Мы пытаемся сделать перегрузку функций по типу аргумента col.
Тип аргумента функции записывается слева от имени аргумента, поэтому:
поэтому в enable_if следует анализировать именно эти типы (которые я указал в апострофах), а не Collection. Тут следует подметить, что в коде выше по ветке я упустил const — это, вообще говоря, ошибка, но она ничего не меняет.
Так же в условиях enable_if тип аргумента можно заменить на эквивалентный, поэтому для примера rg45
Здравствуйте, sergii.p, Вы писали:
SP>пример упрощённый. Конечно дальше нужно перемещать объект. SP>Хотя может лучше впилить один const_cast, чем городить enable_if-ы. Уж точно читабельнее.
стоп, туплю. Может же перемещаться константный объект, так что const_cast отпадает
Здравствуйте, sergii.p, Вы писали:
SP>стоп, туплю. Может же перемещаться константный объект, так что const_cast отпадает
Перемещение может менять состояние исходного объекта, что противоречит константности. Move constructor принимает неконстантную rvalue ссылку, иначе, это не move конструктор. В стандартной библиотеке и бусте, все константные объекты только копируются. Хотя, написать можно что угодно, конечно.