В чем разница между типом (myVar) и (типом) myVar?

Я прохожу полное руководство на cplusplus.com, кодирую и компилирую каждый пример вручную. Регулярно я сталкиваюсь с тем, что вызывает у меня недоумение.

В настоящее время я изучаю этот раздел: http://www.cplusplus.com/doc/tutorial/structures/ . Есть некоторые тонкости, которые можно легко упустить из виду, только читая учебник. Преимущество ввода всего вручную состоит в том, что такие детали выделяются.

На приведенной выше странице есть две примеры программ. У одной есть эта строка:

stringstream(mystr) >> yours.year;

У другой есть эта строка:

(stringstream) mystr >> pmovie->year;

Что я не понимаю, так это разницу (если есть) между типом (myVar) = x; и ( тип) myVar = x; .

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

  • Есть ли разница?
  • Есть ли предпочтительный способ сделать это одним способом, а не другим?

15
задан StoryTeller - Unslander Monica 4 April 2018 в 06:22
поделиться

2 ответа

Нет разницы между типом (x) и (типом) x . Эти два полностью эквивалентны. Большинство людей предпочитают type (x) для классов и (type) x для неклассовых типов, но это остается на ваше усмотрение. Оба вызывают конструкторы для классов с одним аргументом x .

Предпочтительным способом для классов является type (x) , потому что это позволяет передавать более одного аргумента конструктору, как в type (x, y) . Пытаясь применить другую форму, (type) x, y не будет работать: он приводит x , а затем применяет оператор запятой и вычисляет y изолированно . Круглые скобки типа (type) (x, y) не помогают: это вычислит x и y изолированно с помощью оператора запятой, а затем приведёт y от до типа .

Для неклассовых типов такое приведение часто оказывается слишком мощным. В C ++ есть static_cast (x) для грубого выполнения обратного неявного преобразования (например, приведение базовых классов к производным классам и приведение void * к другому указателю), что часто это то, что подходит. См. Когда следует использовать static_cast, dynamic_cast и reinterpret_cast? . Однако

stringstream не является функцией. Выполнение function (x) вызовет это как функцию, но выполнение (function) x недопустимо, потому что есть два выражения рядом друг с другом, без оператора между ними.


Для тех, кто не верит этому ответу и отрицательно оценивает его интуитивно, обратитесь к Стандарту на 5.2.3 / 1

Спецификатор простого типа (7.1.5), за которым следует заключенный в скобки список-выражений конструирует значение указанного типа с учетом списка выражений. Если список выражений является одним выражением, выражение преобразования типа эквивалентно (по определенности и, если определено по смыслу) соответствующему выражению приведения (5.4).

56
ответ дан 1 December 2019 в 00:02
поделиться

Цитируемая вами страница не является тем, что я считаю авторитетным специалистом по C ++ в целом.

В любом случае,

(stringstream) mystr >> pmovie-> year;

преобразует std :: string в объект std :: stringstream . Это актерский состав в стиле C. Скорее опасно, если вы не знаете, что делаете. Это создаст объект stringstream , и значение будет извлечено до pmovie-> year следующим.

stringstream (mystr) >> yours.year;

Создает анонимный объект std :: stringstream и инициализирует его с помощью mystr , а затем значение извлекается в ] pmovie-> год . Объект исчезает в конце своей лексической области, которая в данном случае будет ; в конце строки.

Не большая разница (как уже отмечали другие) между двумя объектами класса w.r.t.

С другой стороны, с идентификаторами (функций / макросов) это становится сложным: function (myVar) = x; работает независимо от того, является ли function реальной функцией или макрос. Однако (функция) (myVar) = x; работает только для реальных функций.

Некоторым стандартным идентификаторам библиотек разрешено иметь обе формы (особенно tolower и его друзья), и поэтому, если вы хотите вызывать функцию всегда, вам следует выбрать первую.

4
ответ дан 1 December 2019 в 00:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: