Да, добавление перегрузки string
, как вы предлагаете, является хорошей идеей. Даже без ссылок на rvalue такая перегрузка была бы хорошей идеей. В противном случае, учитывая std::string s
, для его использования пришлось бы:
x.set_data(s.c_str());
тогда как
x.set_data(s);
намного более интуитивно понятен (и даже немного эффективнее) для клиентов X
.
В качестве другого варианта вы можете добавить эти две перегрузки:
void set_data(const string& s) {internal = s;}
void set_data(string&& s) {internal = std::move(s);}
Это примерно эквивалентно единственной перегрузке, которую вы правильно предложили. Решение с двумя перегрузками дает очень небольшое преимущество в производительности. Решение с одинарной перегрузкой будет стоить дополнительной конструкции string
перемещения, если переданный аргумент является значением x (значение l, которое было преобразовано с помощью std::move
). Но конструктор перемещения std::string
должен быть очень быстрым, так что это не должно иметь большого значения. Я упоминаю об этом только в духе полного раскрытия.
Если set_data
имеет более одного параметра, подход "по значению" становится гораздо более привлекательным. Например, рассмотрим случай, когда вам нужно передать два string
. Ваш выбор:
Решение 1
void set_data(string s1, string s2);
Решение 2
void set_data(const string& s1, const string& s2);
void set_data( string&& s1, const string& s2);
void set_data(const string& s1, string&& s2);
void set_data( string&& s1, string&& s2);
Как вы можете быстро заметить, Решение 2 плохо масштабируется с количеством параметров.
Наконец, ни при каких обстоятельствах вы не должны пытаться применять оба решения к одному и тому же типу:
Не делайте этого!
void set_data(string s) {internal = std::move(s);}
void set_data(const string& s) {internal = s;}
void set_data(string&& s) {internal = std::move(s);}
Этот набор перегрузок будет неоднозначным. Как и в C++03, следующие две перегрузки неоднозначны:
void set_data(string s) {internal = std::move(s);}
void set_data(const string& s) {internal = s;}
Никогда не перегружайте значение по значению ссылкой, будь то ссылка lvalue или ссылка rvalue.
person
Howard Hinnant
schedule
16.11.2012