Я читал это сообщение.
И я дошел до следующего кода.
Я размышлял:
Является std::move
полезно для строк (при условии, что строка достаточно длинная)?
Это делает недействительной предыдущую строку?
Где я должен его использовать, а где нет?
.
class Name
{
public:
Name(std::string firstName, std::string lastName)
: firstName_(std::move(firstName))
, lastName_(std::move(lastName)) {}
void print() const
{
std::cout << lastName_ << ", " << firstName_ << '\n';
}
private:
std::string firstName_;
std::string lastName_;
};
Моя техника всегда использовала
constructor(const std::string& argument): field(argument)
Фраза принятия параметров по значению имеет смысл, когда значение подвижного типа потребляются. С потребляя значение Я имею в виду, что значение передается чему-то, что требует его собственной копии значения. Причина здесь в следующем:
std::move(arg)
).T const&
параметр, и дополнительная операция перемещения считается сравнительно дешевой.Таким образом, ожидается, что в худшем случае может быть небольшая дополнительная работа, но в обычном случае работы существенно меньше, поскольку выполняется только одна операция перемещения вместо копирования.
За std::string
Аргумент немного сложнее, чем для других подвижных типов, из-за довольно распространенной оптимизации коротких строк: вместо нескольких операций с указателями может потребоваться передача байтов. Однако на практике копирование короткой строки или указателей фактически memcpy()
потенциально может сопровождаться операцией, указывающей, что источник операции перемещения больше не содержит строку, которую необходимо освободить.
Таким образом, простое правило
При использовании подвижного объекта принимайте аргумент по значению и перемещайте объект, а не передавайте аргумент через
T const&
и создайте копию, чтобы использовать результат.
Других решений пока нет …