Добавить 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работает.

Другие вопросы по тегам