Добавить int в std::string
Я попробовал два разных способа добавить int
к std::string
и, к моему удивлению, я получил разные результаты:
#include <string>
int main()
{
std::string s;
s += 2; // compiles correctly
s = s + 2; // compiler error
return 0;
}
Почему он компилируется и работает правильно, когда я использую +=
оператор, но не удается, когда я использую +
оператор?
Я не думаю, что вопрос как Как объединить std::string и int?
В этом вопросе нет ответа +=
оператор. И разница между +=
а также +
оператор std::string
это ключ, чтобы решить мои сомнения.
Честно говоря, этот вопрос является хорошим примером для объяснения того, почему с ++ так сложно освоить.
4 ответа
TL;DR operator+=
является функцией-членом класса в class string
, в то время как operator+
это шаблонная функция
Стандартный класс template<typename CharT> basic_string<CharT>
перегружена функция basic_string& operator+=(CharT)
и строка просто basic_string<char>
,
Поскольку значения, которые соответствуют более низкому типу, могут быть автоматически преобразованы в этот тип в выражении s += 2
, 2 не рассматривается как int
, но char
вместо. Это имеет точно такой же эффект, как s += '\x02'
, Добавляется символ с кодом ASCII 2 (STX), а не символ "2" (со значением ASCII 50 или 0x32).
Однако строка не имеет перегруженной функции-члена, такой как string operator+(int)
, s + 2
не является допустимым выражением, поэтому выдает ошибку во время компиляции. (Подробнее ниже)
Вы можете использовать оператор + функция в строке следующими способами:
s = s + char(2); // or (char)2
s = s + std::string(2);
s = s + std::to_string(2); // C++11 and above only
Для людей, обеспокоенных тем, почему 2 не приводится автоматически к char
с operator+
,
template <typename CharT>
basic_string<CharT>
operator+(const basic_string<CharT>& lhs, CharT rhs);
Выше приведен прототип [примечание] для оператора плюс в s + 2
и поскольку это шаблонная функция, она требует реализации обоих operator+<char>
а также operator+<int>
, что является противоречивым. Подробнее см. Почему автоматическое понижение рейтинга не применяется к функциям шаблона?
Между тем, прототип operator+=
является:
template <typename CharT>
class basic_string{
basic_string&
operator+=(CharT _c);
};
Видите ли, здесь нет шаблона (это функция-член класса), поэтому компилятор выводит, что тип CharT char
от реализации класса, и int(2)
автоматически вливается в char(2)
,
Примечание. При копировании из стандартного исходного кода C++ ненужный код удаляется. Это включает в себя имя 2 и 3 (Traits and Allocator) для шаблонного класса "basic_string" и ненужные подчеркивания, чтобы улучшить читаемость.
s += 2;
не делает то, что вы думаете, что делает. Вызывает перегруженный +=
оператор к char
, Не добавляет символ '2'
, а скорее символ со значением 2, и результат будет зависеть от кодировки, используемой на вашей платформе.
Оператор не перегружен, чтобы разрешить s + 2
составить1. Отсюда и ошибка.
Решение в обоих случаях заключается в использовании std::to_string(2)
а не int
буквальный 2.
1 По сути, причина в том, что operator+=
это не шаблонная функция, но std::operator+
и разрешение перегрузки предпочтительнее не шаблонной функции, а шаблонной.
Правильный способ добавить к вашему string
было бы
std::string s;
s += std::to_string(2);
s = s + std::to_string(2);
Хотя ответ @CoryKramer дает вам правильный способ добавить целое число в строку, он не объясняет, почему инструкция s = s + 2
не компилируется.
Разница между этими двумя инструкциями заключается в том, что в первой вы используете std::string
' + + оператор во время второй инструкции, компилятор пытается привести 2
в строку.
Не существует неявного преобразования между int
а также std::string
, Тем не менее, вы можете разыграть int
в char
вот почему s += 2
работает.