Передача std :: string по значению или по ссылке [duplicate]

Possible Duplicate:
Are the days of passing const std::string & as a parameter over?

Должен ли я пройтиstd::string по значению или по ссылке (на не встроенную функцию), если семантика перемещения поддерживается? А как насчет реализаций, использующих небольшую строковую оптимизацию (SSO)?

 Nordlöw28 мая 2012 г., 21:50
@ linuxuser27: Ааа, хороший вопрос. Ответ, конечно, зависит от этого ... В некоторых случаях я просто читаю его, в других я объединяю его вместе с каталогами для построения путей. Я считаю, что я должен передать значение, когда я хочу изменить его, чтобы сработали конструкторы перемещения. А как насчет случаев только для чтения - с помощью постоянной ссылки?
 linuxuser2728 мая 2012 г., 21:47
Что вы собираетесь делать со строкой в функции?

Ответы на вопрос(3)

Я считаю нормальным ответом является то, что он должен быть передан по значению, если вам нужно сделать копию этого в вашей функции. В противном случае передайте его по ссылке.

Вот хорошая дискуссия:http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/

Решение Вопроса

Есть несколько ответов, основанных на том, что вы делаете со строкой.

1) Использование строки в качестве идентификатора (не будет изменено). Передача его по константной ссылке, вероятно, лучшая идея здесь:(std::string const&)

2) Изменить строку, но не желая, чтобы вызывающая сторона увидела это изменение. Передача его по значению предпочтительнее:(std::string)

3) Изменение строки, но чтобы вызывающий абонент увидел это изменение. Передача по ссылке предпочтительнее:(std::string &)

4) Отправка строки в функцию, и вызывающая функция больше никогда не будет использовать строку. С помощьюпереместить семантику может быть вариант(std::string &&)

 06 мар. 2016 г., 03:17
@ BenjaminLindley Совсем нет,&& предотвращает случайную передачу аргумента копией.
 06 мар. 2016 г., 03:26
@Destructor конструируетstd::string из строкового литерала и передает его в качестве аргумента. Затем он копирует конструирует членскую строку из аргумента. Таким образом, два выделения и две O (n) операции копирования массива (для каждого аргумента). Вы должны принять параметры по значению иstd::move их в члены. Таким образом, это будет только одно выделение, одна копия массива O (n) и одно перемещение O (1) на аргумент.
 Nordlöw28 мая 2012 г., 21:55
Случай 3) необходим, только еслиstd::string реализация не поддерживает семантику перемещения, верно?
 28 мая 2012 г., 23:43
# 4 не является необходимым, поскольку об этом можно и нужно заботиться на стороне вызывающего абонента, используяstd::move на его аргумент и вызывая версию по значению.
 28 мая 2012 г., 21:59
@ Nordl & # xF6; w Не совсем. Семантика перемещения интересна тем, что перемещает данные, а не копирует их. В приведенном выше случае семантика перемещенияchar * вstd::string от вызывающей функции к вызываемой функции. Если вы используете семантику перемещения для передачи значения, строка больше не будет в функции вызывающей стороны, если вы не передадите ее обратно. Смотрите ссылку выше, говоря о семантике перемещения.

Проверьтеэтот ответ для C ++ 11, В основном, если вы передаете lvalue ссылку на rvalue

ОтЭта статья:

void f1(String s) {
    vector<String> v;
    v.push_back(std::move(s));
}
void f2(const String &s) {
    vector<String> v;
    v.push_back(s);
}

& quot; Для аргумента lvalue, & # x2018; f1 & # x2019; имеет одну дополнительную копию для передачи аргумента, поскольку он является побочным значением, в то время как & # x2018; f2 & # x2019; есть одна дополнительная копия для вызова push_back. Так что нет разницы; для аргумента rvalue компилятор должен создать временную строку & # x2018; String (L & # x201C; & # x201D;) & # x2019; и передать временный номер & # x2018; f1 & # x2019; или & # x2018; f2 & # x2019; тем не мение. Потому что & # x2018; f2 & # x2019; может использовать перемещение ctor, когда аргумент является временным (что является r-значением), затраты на его передачу теперь одинаковы для & # x2018; f1 & # x2019; и & # x2018; f2 & # x2019;. & quot;

Продолжение: & Quot; Это означает, что в C ++ 11 мы можем повысить производительность, используя подход с передачей по значению, когда:

The parameter type supports move semantics - All standard library components do in C++11 The cost of move constructor is much cheaper than the copy constructor (both the time and stack usage). Inside the function, the parameter type will be passed to another function or operation which supports both copy and move. It is common to pass a temporary as the argument - You can organize you code to do this more.

& Quot;

OTOH, для C ++ 98 лучше всего передавать по ссылке - копируется меньше данных. Передача const или non const зависит от того, нужно ли вам изменить аргумент или нет.

Ваш ответ на вопрос