Почему не удается передать lvalue в качестве аргумента rvalue? - PullRequest
0 голосов
/ 30 января 2019

Передача ссылки lvalue в качестве аргумента ссылки rvalue не компилируется.Компилятор может создать временный объект с его конструктором копирования и передать его как значение, но это не так.Тем не менее, он вызывает конструктор, если типы не совпадают.

Мне интересно, почему он работает таким образом?Какая логика проектирования здесь в стандарте C ++, которая заставляет компилятор обрабатывать конструктор копирования по-другому?

void do_smth(string && s)
{}

void f(const char * s)
{
  do_smth(s); // passes a temporary string constructed from const char*
}

void g(const string & s)
{
  do_smth(s); // does not compile
}

void h(const string & s)
{
  do_smth(string(s)); // ok again
}

Что мне делать, если я не хочу реализовывать вторую сигнатуру do_smth(const string &)?Должен ли я вместо этого использовать передачу по значению void do_smth(string s)?

Какие существуют другие различия между значениями void do_smth(string s) и rvalue-reference void do_smth(string && s), если объект string имеет конструктор перемещения?

Ответы [ 2 ]

0 голосов
/ 30 января 2019

В этом весь смысл ссылок на 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, полностью зависит от того, что "что-то" собирается "сделать", и только вы можете сказать, что это такое.

0 голосов
/ 30 января 2019

in h вы даете non const копию строки const , поэтому const исчезает противоположно g case

, конечно, с void do_smth(string s){...} копия создается при вызове, и обе const и неконстантная строка могут быть заданы в аргументе

...