clang-tidy предлагает удалить константные ссылки, почему? - PullRequest
6 голосов
/ 10 апреля 2020

Я запустил clang-tidy («модернизировать» модули) в дереве проекта, которое я пытался поддерживать в актуальном состоянии с C ++ 17. Почти все, что исправлялось, было для меня неожиданным, за исключением одного: он изменил все эти типы конструкций:

void foo(const std::string& str) {
}

.. на это:

void foo(std::string str) {
}

И я не не понимаю почему. На мой неподготовленный глаз это означало бы две вещи:

  1. . Это должно было бы скопировать объект, а не просто передать ссылку. (Хотя я предполагаю, что бывают ситуации, когда компилятор может сделать вывод, что он может просто передать указатель при генерации кода - но ссылка делает его явным (что лучше imho)).
  2. Const есть сказать разработчику тела функции, что он не должен изменять входную строку, и что, если ему нужно изменить строку, ему нужно где-то хранить свою собственную копию.

Я действительно вижу положительный эффект - просто передавая объект в виде ссылки const, это просто «удалить константное» приведение, которое в любом случае не будет изменено, поэтому я предполагаю, что передача по значению решит эту проблему.

Почему он рекомендует удалять константные ссылки с неконстантными проходными значениями?

1 Ответ

7 голосов
/ 10 апреля 2020

Обоснование, данное здесь , равно

С семантикой перемещения, добавленной к языку, и стандартной библиотекой, дополненной конструкторами перемещения, добавленными для многих типов, теперь интересно принять аргумент непосредственно по значению, а не по const-ссылке, а затем скопировать. Эта проверка позволяет компилятору позаботиться о выборе наилучшего способа создания копии.

Дополнительно

Преобразование обычно полезно, когда вызывающий код передает значение r и Предполагается, что переезд является дешевой операцией.

Однако в документации говорится, что единственная замена выполняется в следующем конкретном c случае:

Заменяет использование параметров конструктора const-reference, которые копируются в поля класса. Затем параметр перемещается с помощью std :: move ().

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

Поэтому я не все ваши функции должны были быть преобразованы таким образом.

...