Анализатор обнаружил, что переменная не используется после того, как её скопировали в другую переменную. Такой код можно оптимизировать, избавившись от лишнего копирования.
Рассмотрим несколько ситуаций.
Пример 1:
class UserInfo { std::string m_name; public: void SetName(std::string name) { m_name = name; } };
В приведённом примере произойдёт два копирования: первое при вызове функции 'SetName()', второе при копировании 'name' в 'm_name'. Можно избавиться от копирования, использовав move присвоение:
void SetName(std::string name) { m_name = std::move(name); }
Если объект не move assignable, то можно изменить сигнатуру функции 'SetName()', сделав переменную 'name' константной ссылкой. В таком случае копирование произойдёт только при присваивании.
void SetName(const std::string &name) { m_name = name; }
Пример 2:
bool GetUserName(int id, std::string &outName) { std::string tmp; if (db->GetUserName(id, tmp)) { outName = tmp; return true; } return false; }
В данном случае есть локальная переменная 'tmp', которая копируется в 'outName' и дальше не используется. С точки зрения производительности эффективнее использовать 'move' или 'swap'.
bool GetName(int id, std::string &outName) { std::string tmp; if (db->GetUserName(id, tmp)) { outName = std::move(tmp); return true; } return false; }
Пример 3:
void Foo() { std::vector<UserInfo> users = GetAllUsers(); { std::vector<UserInfo> users1 = users; DoSomethingWithUsers1(users1); } { std::vector<UserInfo> users2 = users; DoSomethingWithUsers2(users2); } }
Иногда копирование можно заменить на ссылку, если вариант с swap/move для какого-то класса недоступен. Это может быть не лучшим решением с точки зрения красоты кода, но это будет лучше по производительности.
void Foo() { std::vector<UserInfo> users = GetAllUsers(); { std::vector<UserInfo> users1 = users; DoSomethingWithUsers1(users1); } { std::vector<UserInfo> &users2 = users; DoSomethingWithUsers2(users2); } }