Объединение двух строковых литералов

Я очень новичок в программировании, и я читаю «Ускоренный C ++» Кенига. В любом случае, я изучаю строки, и он пишет, что «новая идея состоит в том, что мы можем использовать + для конкатенации строки и строкового литерала – или, если на то пошло, две строки (но не две строковые литералы).

Хорошо, это имеет смысл, я полагаю. Теперь на два отдельных упражнения, предназначенных для освещения этого.

Имеются ли следующие определения?

const string hello = "Hello"; const string message = hello + ",world" + "!"; 

Теперь я попытался выполнить выше, и это сработало! Поэтому я был счастлив.

Затем я попытался сделать следующее упражнение;

 const string exclam = "!"; const string message = "Hello" + ",world" + exclam; 

Это не сработало. Теперь я понимаю, что это связано с тем, что вы не можете конкатенировать два строковых литерала, но я не понимаю семантической разницы между тем, почему мне удалось получить первый пример для работы (это не «мир» и «! «Два строковых литерала? Не могли бы это не сработать?), но не во втором.

Спасибо!

 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 затем объединяется с std::string "!" ,


Что касается того, почему вы не можете конкатенировать два строковых литерала с помощью + , это потому, что строковый литерал – это просто массив символов ( const char [N] где N – длина строки плюс одна, для нулевого терминатора). Когда вы используете массив в большинстве контекстов, он преобразуется в указатель на его исходный элемент.

Итак, когда вы пытаетесь выполнить "Hello" + ",world" , то, что вы действительно пытаетесь сделать, это добавить два const char* s вместе, что невозможно (что означало бы добавить два указателя вместе?) и если бы это было, это не сделало бы того, что вы хотели этого сделать.


Обратите внимание, что вы можете конкатенировать строковые литералы, помещая их рядом друг с другом; например, следующие два эквивалентны:

 "Hello" ",world" "Hello,world" 

Это полезно, если у вас длинный строковый литерал, который вы хотите разбить на несколько строк. Однако они должны быть строковыми литералами: это не будет работать с указателями const char* или массивами const char[N] .

Вы всегда должны обращать внимание на типы .

Хотя все они кажутся струнами, "Hello" и ",world" являются литералами .

И в вашем примере exclam является объектом std::string .

C ++ имеет перегрузку оператора, которая принимает объект std::string и добавляет к нему другую строку. Когда вы объединяете объект std::string с литералом, он сделает соответствующее литье для литерала.

Но если вы попытаетесь объединить два литерала, компилятор не сможет найти оператора, который принимает два литерала.

Второй пример не работает, потому что для двух строковых литералов нет operator + . Обратите внимание, что строковый литерал не имеет string типа, но вместо этого имеет тип const char * . Ваш второй пример будет работать, если вы его переработаете следующим образом:

 const string message = string("Hello") + ",world" + exclam; 

В случае 1, из-за порядка операций вы получаете:

(привет + “, мир”) + “!” который решает привет + “!” и, наконец, приветствовать

В случае 2, как отметил Джеймс, вы получаете:

(«Hello» + «, world») + exclam, который является конкат двумя строковыми литералами.

Надеюсь, это понятно 🙂

Разница между строкой (или, если быть точнее, std::string ) и символьным литералом заключается в том, что для последнего не существует оператора + . Вот почему второй пример терпит неудачу.

В первом случае компилятор может найти подходящий operator+ первым аргументом которого является string а второй – символьный литерал ( const char* ), чтобы он использовал это. Результатом этой операции снова является string , поэтому она повторяет тот же трюк при добавлении "!" к нему.

  • Каковы правила, регулирующие использование скобок в вызовах функций VBA?
  • В Java можно определить целочисленную константу в двоичном формате?
  • Как подчеркивается символ подчеркивания перед переменной в classе цели-c cocoa?
  • Как я могу разделить команду оболочки на несколько строк при использовании оператора IF?
  • Когда были введенные в C ++ «и» и «или» альтернативные токены?
  • Что такое разбивка на синтаксис лямбды Java?
  • Точечная нотация и обозначение сообщений для объявленных свойств
  • Что означает функция%>% в R?
  • 3 плюс символы между двумя переменными (например, +++ b) в C
  • Назначение массива c ++ для нескольких значений
  • Почему переменные конструктора конструктора объекта C # 3.0 необязательны?
  • Interesting Posts

    Есть ли кабель с 2.5 "(44-контактным) IDE на обоих концах или альтернатива для подключения SATA-накопителя к ноутбуку IDE?

    Слияние Сортировка связанного списка

    Не удается щелкнуть правой кнопкой мыши на значке панели задач Windows 10

    Какую информацию о вашем ПК можно получить на сайтах / в Интернете?

    Регулярное выражение для проверки имен и фамилий?

    Как перебрать HashMap с помощью JSTL forEach?

    Как Chrome может искать среди заголовков / URL уже открытых вкладок, например Firefox?

    Firebase: установить правила безопасности в зависимости от пользовательских ролей

    Как автоматически перезапустить фоновый процесс linux, если он не работает?

    Как я могу суммировать свои данные по неделям?

    Как создать круговой (бесконечный) RecyclerView?

    Windows 10 продолжает показывать 100% использования ЦП независимо от того, что

    Как получить индекс с помощью LINQ?

    Вставить фид активности общедоступной страницы Facebook, не заставляя пользователя входить в систему / разрешать

    Есть ли опция / функция MySQL для отслеживания истории изменений записей?

    Давайте будем гением компьютера.