В данный момент я изучаю C ++ и стараюсь не приобретать вредных привычек. Насколько я понимаю, clang-tidy содержит множество "лучших практик", и я стараюсь придерживаться их как можно лучше (хотя я не всегда понимаю, почему они считаются хорошими), но я не уверен, что поймите, что здесь рекомендуется.
Я использовал этот класс из учебника:
class Creature
{
private:
std::string m_name;
public:
Creature(const std::string &name)
: m_name{name}
{
}
};
Это приводит к предложению clang-tidy передавать по значению вместо ссылки и использования std::move. Если я делаю, я получаю предложение сделать nameссылку (чтобы убедиться , что он не копируется каждый раз) и предупреждение , что std::moveне будет иметь никакого эффекта , потому что nameэто constтак , я должен удалить его.
Единственный способ не получить предупреждения - это constполностью удалить :
Creature(std::string name)
: m_name{std::move(name)}
{
}
Что кажется логичным, поскольку единственным преимуществом constбыло предотвращение путаницы с исходной строкой (чего не происходит, потому что я передал по значению). Но я читал на CPlusPlus.com :
Обратите внимание, что в стандартной библиотеке перемещение подразумевает, что перемещаемый объект остается в допустимом, но неуказанном состоянии. Это означает, что после такой операции значение перемещенного объекта должно быть только уничтожено или присвоено новое значение; в противном случае доступ к нему дает неопределенное значение.
А теперь представьте этот код:
std::string nameString("Alex");
Creature c(nameString);
Поскольку nameStringпередается по значению, он std::moveбудет признан недействительным только nameвнутри конструктора и не затронет исходную строку. Но каковы преимущества этого? Похоже, что контент копируется только один раз - если я передаю по ссылке при вызове m_name{name}, если я передаю по значению, когда передаю его (а затем он перемещается). Я понимаю, что это лучше, чем передавать по значению и не использовать std::move(потому что он копируется дважды).
Итак, два вопроса:
- Правильно ли я понял, что здесь происходит?
- Есть ли какие-то преимущества использования
std::moveпересылки по ссылке и простого вызоваm_name{name}?
Creature c("John");делает дополнительную копию