В этом весь смысл ссылок на rvalue.Они связываются с rvalues , а not to lvalues .
Таким образом вы гарантируете, что требуемая перегрузка вызывается, когда у вас естьи версия lvalue и версия rvalue.Например, конструктор копирования против конструктора перемещения.
Это особенность.
Кроме того, ваше lvalue равно const
, что не соответствует сигнатуре do_smth
, даже если оно имело местоне принимать ссылку на rvalue.
Если вы хотите, чтобы do_smth
мог принимать выражение или , либо сделайте его const string&
, либо сделайте его шаблоном и получитедля этого требуется ссылка для пересылки T&&
(которая выглядит как ссылка на rvalue, но не совсем).
Если вы хотите от do_smth
до сохраните свою собственную версию строки , затем примите значение: вы все равно можете избежать копирования, если нужно, используя std::move
на месте вызова (или передавая значение rvalue, которое вызовет собственный конструктор перемещения строки).
Посмотрите, как все опции доступны и изящны, благодаря тому, как создаются правила привязки ссылки rvalue?Все это сходится воедино.
Решение о том, что разрешить do_smth
, полностью зависит от того, что "что-то" собирается "сделать", и только вы можете сказать, что это такое.