Я бы не беспокоился об этом. Если вы делаете это в цикле, строки всегда будут предварительно выделять память, чтобы минимизировать перераспределение - просто используйте operator+=
в этом случае. И если вы делаете это вручную, что-то вроде этого или дольше
a + " : " + c
Затем он создает временные файлы, даже если компилятор может исключить некоторые копии возвращаемых значений. Это связано с тем, что в последовательно вызываемом operator+
он не знает, ссылается ли ссылочный параметр на именованный объект или на временное значение, возвращаемое из вызова sub operator+
. Я предпочел бы не беспокоиться об этом, прежде чем не будет профилировать в первую очередь. Но давайте возьмем пример для демонстрации этого. Сначала мы вводим скобки, чтобы сделать привязку понятной. Я помещаю аргументы непосредственно после объявления функции, которое используется для ясности. Ниже я покажу, каково тогда полученное выражение:
((a + " : ") + c)
calls string operator+(string const&, char const*)(a, " : ")
=> (tmp1 + c)
Теперь, в этом добавлении, tmp1
- это то, что было возвращено первым вызовом оператора + с указанными аргументами. Мы предполагаем, что компилятор действительно умен и оптимизирует копию возвращаемого значения. Таким образом, мы получаем одну новую строку, которая содержит объединение a
и " : "
. Теперь это происходит:
(tmp1 + c)
calls string operator+(string const&, string const&)(tmp1, c)
=> tmp2 == <end result>
Сравните это со следующим:
std::string f = "hello";
(f + c)
calls string operator+(string const&, string const&)(f, c)
=> tmp1 == <end result>
Он использует одну и ту же функцию для временной и именованной строки! Таким образом, компилятор имеет , чтобы скопировать аргумент в новую строку, добавить к нему и вернуть его из тела operator+
. Он не может взять временную память и добавить к этому. Чем больше выражение, тем больше копий строк должно быть сделано.
Далее Visual Studio и GCC будут поддерживать семантику перемещения c ++ 1x (дополняющую семантику копирования ) и ссылки на значения в качестве экспериментального дополнения. Это позволяет выяснить, является ли параметр временным или нет. Это сделает такие добавления удивительно быстрыми, так как все вышеперечисленное закончится в одном «add-pipe» без копий.
Если это оказывается узким местом, вы все равно можете сделать
std::string(a).append(" : ").append(c) ...
Вызовы append
добавляют аргумент к *this
и затем возвращают ссылку на себя. Таким образом, там нет копирования временных файлов. Или, в качестве альтернативы, можно использовать operator+=
, но для исправления приоритета вам потребуются ужасные скобки.