Какова цель самого Vexing Parse?

В Википедии я нашел это:

A a( A() );

[Это] можно было бы устранить

  1. определение переменной класса [ A ], взятие анонимного экземпляра класса [ A ] или

  2. объявление функции для функции, которая возвращает объект типа [ A ] и принимает один (неименованный) аргумент, который является функцией, возвращающей тип [ A ] (и без ввода).

Большинство программистов ожидают первого, но стандарт C++ требует, чтобы он интерпретировался как второй.

Но почему? Если большинство C++ сообщество ожидает прежнего поведения, почему бы не сделать его стандартным? Кроме того, приведенный выше синтаксис является последовательным, если вы не учитываете неоднозначность разбора.

Может кто-нибудь, пожалуйста, просветит меня? Почему стандарт делает это требование?

Ответ 1

Пусть говорят, что MVP не существует.

Как бы вы объявили функцию?

A foo();

было бы определением переменной, а не объявлением метода. Вы представили бы новое ключевое слово? У вас будет более неудобный синтаксис для объявления функции? Или вы бы предпочли

A foo;

определить переменную и

A foo();

объявить функцию?

Ваш немного более сложный пример - это просто согласование с этим базовым. Легче сказать "все, что может быть истолковано как объявление, будет интерпретироваться как объявление", а не "все, что может быть истолковано как объявление", будет интерпретироваться как объявление, если только это не определение одной переменной, и в этом случае это переменное определение ".

Вероятно, это не мотивация, хотя причина - это хорошо.

Ответ 2

Это всего лишь предположение, но это может быть связано с тем, что при данном подходе вы можете получить оба поведения:

A a( A() ); // this is a function declaration
A a( (A()) ); // this is a variable definition

Если бы вы изменили свое поведение на определение переменной, то объявления функций были бы значительно более сложными.

typedef A subfunction_type();

A a( A() ); // this would be a variable declaration
A a( subfunction_type ); // this would be a function declaration??

Ответ 3

Для C++ это довольно просто: потому что правило было сделано таким образом в C.

В C двусмысленность возникает только с помощью typedef и некоторого довольно неясного кода. Почти никто никогда не запускает его случайно - на самом деле, он, вероятно, считается редким, за исключением кода, специально разработанного для демонстрации возможности. Однако, к лучшему или к худшему, простая возможность двусмысленности означала, что кто-то должен был ее разрешить - и если память служит, она была разрешена не кем иным, как Деннисом Ритчи, который постановил, что все, что может быть истолковано как выражение, будет декларация, даже если в качестве определения была также неоднозначная интерпретация.

C++ добавила возможность использовать круглые скобки для инициализации, а также вызовы функций как группировки, и это переместило его двусмысленность от неясного к общему. Однако изменение этого правила потребовало бы нарушения правила, поскольку оно исходило из C. Решение этой конкретной двусмысленности, как ожидало большинство, без создания еще полдюжины, которые были бы еще более удивительными, вероятно, были бы довольно нетривиальными, если только вы были готовы полностью отказаться от совместимости с C.

Ответ 4

Его побочный эффект грамматики определяется рекурсивно.

Это не было специально спроектировано. Он был обнаружен и задокументирован как самый неприятный синтаксический анализ.

Ответ 5

Никакой конкретной причины, кроме [возможно] случая, который идентифицирует K-ballo.

Это просто наследие. Уже был int x; так что никогда не казалось, что требуется T x; когда никакие ctor args не играют.

Оглядываясь назад, я бы предположил, что если бы язык был разработан с нуля сегодня, тогда MVP не существовал бы... наряду с тонкостью других C++ странностей.

Напомним, что C++ развивался на протяжении десятилетий и даже сейчас разработан только комитетом (см. Также: верблюд).