Что именно происходит, когда символ добавляется к строковому литералу с помощью оператора «+» в C ++? - PullRequest
4 голосов
/ 10 марта 2011

Основываясь на моем чтении, следующий код:

string aggregate = "give" + 'n';

Должен выдать результирующую строку со значением:

"данное".

Вместо этого он производит мусор,Почему не происходит следующее?

  1. "give" преобразуется в std :: string через конструктор, который принимает указатель на массив символов.

  2. Перегрузка '+', которая принимает std :: string и вызывается символ, возвращая новую строку.

Я основываю свою теорию на this man page.

Теперь я слышал, что первый аргумент перегруженного оператора не является кандидатом на преобразование конструктора, если оператор является членом класса.Мне кажется, я читал это в Кениге и Му.Но в этом случае я понимаю, что оператор «+» не является перегрузкой.

Я понимаю, что это кажется нелепым чрезмерным усложнением, но мне нравится знать FOR SURE что происходит, когда я пишу код.

Ответы [ 4 ]

6 голосов
/ 10 марта 2011

Выражение "give" + 'n' вычисляется первым, добавляя (int)'n' к адресу строковой константы "give". Результат этого арифметического указателя присваивается строковому объекту. Ошибка не возникает, потому что результат имеет тип const char*.

Вы должны привыкнуть думать обо всем справа от = как происходящем до фактического назначения (или инициализации в этом случае).

Вы хотите следующее:

// construct the string object first
std::string aggregate = "give";

// then append the character
aggregate += 'n';

или, сначала явно скомпилируйте строковый объект:

std::string aggregate = std::string("give") + 'n';
4 голосов
/ 10 марта 2011

Тот факт, что в левой части выражения есть std::string, не имеет значения для первого шага: "give" - это const char[5], который уменьшается до const char*, а 'n' - это char, то есть целочисленный тип.Добавление целого числа к указателю просто добавляет к адресу указателя.Результат снова имеет тип const char*, который затем неявно преобразуется в std::string.

По сути, ваш код эквивалентен:

const char* c = "a string" + 'n';
std::string s = c;

Итак, для достижения желаемого эффектапопробуйте

std::string s = std::string("a string") + 'n';
2 голосов
/ 10 марта 2011

Вы добавляете целое число 'n' к адресу литерала "give".

Попробуйте это с:

string aggregate = "long string long string long string long string long string long string long string " + 'A';

Это должно проиллюстрировать, что происходит.

1 голос
/ 10 марта 2011

Этот код не делает то, что, как вы думаете, он делает.

Он принимает строковый литерал "give", который затем эффективно ухудшается до const char[5], а затем добавляет целое значение 'n' кэтот указатель.Затем он берет этот новый указатель мусора и пытается сделать из него строку.

Вы хотите string aggregate = std::string("give") + 'n';

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...