Intereting Posts
Проблема с наследованием наложенного / незанятого идентификатора C ++ Шаблон classа C ++ для определенного базового слоя Как запустить код сборки без создания нового процесса? Как заставить std :: stringstream operator читать целую строку? Что происходит с близостью streamа объекта QObject, созданного в рабочем streamе, который затем завершается? Замените массивы с фиксированным размером на std :: array? Кодирование снимка экрана в видео с использованием FFMPEG C ++ Удалить повторяющиеся записи в векторе Двоичная воспроизводимость в Visual C ++ Как специализировать функцию члена шаблона для другого classа шаблона? Проверка правильного ввода типа с использованием std :: cin (C ++) Связь между объектным файлом и файлом общего объекта Предупреждение C ++ C4018: ‘<': несоответствие с подписью / без знака boost :: this_thread :: interruption_point () не генерирует boost :: thread_interrupted & exception ошибка: BOOST DISABLE THREADS

Добавить int в std :: string

Я попробовал два разных способа добавить int в std::string , и, к моему удивлению, у меня были разные результаты:

 #include  int main() { std::string s; s += 2; // compiles correctly s = s + 2; // compiler error return 0; } 

Почему он компилируется и работает правильно, когда я использую оператор += , но сбой при использовании оператора + ?

Я не думаю, что вопрос подобен тому, как конкатенировать std :: string и int?

В этом вопросе ни один ответ не использует += operator. И разница между оператором += и + std::string является ключом к решению моих сомнений.

Честно говоря, этот вопрос является хорошим примером для объяснения того, почему c ++ так сложно освоить.

TL; DR operator+= – функция class string , а operator+ – функция шаблона.

Стандартный template basic_string имеет перегруженную функцию basic_string& operator+=(CharT) , а строка – просто basic_string .

Поскольку значения, которые вписываются в более низкий тип, могут быть автоматически добавлены в этот тип, в выражении s += 2 , 2 не рассматривается как int , а char вместо этого. Он имеет тот же эффект, что и s += '\x02' . Добавляется символ с кодом ASCII 2 (STX), а не символ «2» (с значением ASCII 50 или 0x32).

Однако строка не имеет перегруженной функции-члена, такой как string operator+(int) , s + 2 не является допустимым выражением, поэтому выдает ошибку во время компиляции. (Более подробно)

Вы можете использовать функцию operator + в строке следующим образом:

 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  basic_string operator+(const basic_string& lhs, CharT rhs); 

Вышеупомянутый прототип [примечание] для оператора плюс в s + 2 , и поскольку он является функцией шаблона, ему требуется реализация как operator+ и operator+ , что противоречит друг другу. Дополнительные сведения см. В разделе Почему автоматическое подавление применяется к функциям шаблона?

Между тем прототипом operator+= является:

 template  class basic_string{ basic_string& operator+=(CharT _c); }; 

Видите ли, здесь нет шаблона (это функция-член classа), поэтому компилятор выводит, что тип CharT является char из реализации classа, а int(2) автоматически преобразуется в char(2) .


Примечание. Необязательный код удаляется при копировании из стандарта C ++, включая источник. Это включает в себя typename 2 и 3 (Traits and Allocator) для classа шаблона «basic_string» и ненужные подчеркивания, чтобы улучшить удобочитаемость.

s += 2; не делает то, что, по вашему мнению, делает. Он вызывает перегруженный оператор += char . Он не добавляет символ '2' , а скорее символ со значением 2, и результат будет зависеть от кодировки, используемой на вашей платформе.

Перегрузка оператора не определена, чтобы s + 2 скомпилировал 1 . Отсюда и ошибка.

Решение в обоих случаях заключается в использовании std::to_string(2) а не в int literal 2.


1 По сути, причина в том, что operator+= не является функцией шаблона, но std::operator+ is, а разрешение перегрузки будет поддерживать функцию без шаблона над шаблоном.

Правильный способ добавить к вашей string будет

 std::string s; s += std::to_string(2); s = s + std::to_string(2); 

Хотя ответ @CoryKramer дает вам правильный способ добавить целое число в строку, он не объясняет, почему команда s = s + 2 не компилируется.

Разница между двумя инструкциями заключается в том, что в первом случае вы используете оператор std::string ‘s + =, а во второй инструкции компилятор пытается отличить 2 от строки.

Нет никакого неявного преобразования между int и std::string . однако вы можете использовать int для char , поэтому вот почему s += 2 работает.