V820. The variable is not used after copying. Copying can be replaced with move/swap for optimization.
Анализатор обнаружил, что переменная не используется после того, как её скопировали в другую переменную. Такой код можно оптимизировать, избавившись от лишнего копирования.
Рассмотрим несколько ситуаций.
Пример 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);
}
}