const string message = "Hello" + ",world" + exclam;
Оператор +
имеет ассоциативность слева направо, поэтому эквивалентное выражение в скобках:
const string message = (("Hello" + ",world") + exclam);
Как видите, два строковых литерала "Hello"
и ",world"
«добавляются» в первую очередь, поэтому возникает ошибка.
Одна из первых двух сцепляемых строк должна быть std::string
объектом:
const string message = string("Hello") + ",world" + exclam;
В качестве альтернативы, вы можете принудительно вызвать вторую +
нужно сначала вычислить, заключив в скобки эту часть выражения:
const string message = "Hello" + (",world" + exclam);
Имеет смысл, что ваш первый пример (hello + ",world" + "!"
) работает, потому что std::string
(hello
) является одним изаргументы слева +
.То, что +
вычисляется, результатом является std::string
объект с объединенной строкой, а полученный std::string
затем объединяется с "!"
.
Что касается зачем Вы не можете объединить два строковых литерала, используя +
, это потому, что строковый литерал - это просто массив символов (const char [N]
, где N
- длина строки плюс один, для нулевого терминатора).Когда вы используете массив в большинстве контекстов, он конвертируется в указатель на его начальный элемент.
Итак, когда вы пытаетесь сделать "Hello" + ",world"
, то, что вы на самом деле пытаетесь сделать, - это добавить два const char*
вместе, что невозможно (что бы означало добавить два указателя вместе?) и если бы это было так, то не сделал бы то, что хотел.
Обратите внимание, что вы можете объединять строковые литералы, помещая их рядом друг с другом;например, следующие два эквивалента:
"Hello" ",world"
"Hello,world"
Это полезно, если у вас есть длинный строковый литерал, который вы хотите разбить на несколько строк.Однако они должны быть строковыми литералами: это не будет работать с const char*
указателями или const char[N]
массивами.