Подтвердить что ты не робот

Почему в С++ 11 было добавлено возвращающих-возвращаемых типов?

Наконец-то я начал читать c + +11, и я не понимаю, почему требуются типы возвращаемого типа возврата.

Нашел следующий пример, который используется для выделения проблемы:

template<class Lhs, class Rhs>
  decltype(lhs+rhs) adding_func(const Lhs &lhs, const Rhs &rhs) {return lhs + rhs;} 

Пример является незаконным, поскольку decltype(lhs+rhs) не работает, поскольку идентификаторы lhs и rhs действительны только после фазы синтаксического анализа.

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

Я не вижу недостатка в том, что decltype выполняет разрешение типа после завершения синтаксического анализа (что будет отлично работать для приведенного выше примера). Я считаю, что это был бы более простой способ решить проблему...

Вместо этого стандарт С++ 11 предоставляет типы возвращаемых возвратов:

template<class Lhs, class Rhs>
  auto adding_func(const Lhs &lhs, const Rhs &rhs) -> decltype(lhs+rhs) {return lhs + rhs;}

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

Обратно-возвращаемые типы кажутся слишком сложным решением для меня, поскольку разрешение decltype типа после разбора полного тела функции будет работать так же хорошо?

4b9b3361

Ответ 1

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

Недостатком является то, что это невозможно без принципиального изменения основных основ модели синтаксического анализа и обработки С++.

Чтобы сделать то, что вы предлагаете, компилятору придется увидеть синтаксис decltype и сделать базовый лексический анализ содержимого синтаксиса. Затем он продолжает разбирать больше исходного файла. В какой-то более поздний момент (когда?), Он решает пойти "эй, что я раньше смотрел", теперь я сделаю для них всю работу по разбору ".

Как правило, С++ не поддерживает поиск определения символов. Основное предположение структуры синтаксического анализа С++ заключается в том, что если символ не объявлен до его использования, это ошибка компилятора.

Классы могут уйти с поиском, но только в отношении их членов. Частично это объясняется тем, что его четкое выражение, когда выражение id может ссылаться на переменную-член (т.е. Если она не относится к уже объявленной локальной или глобальной переменной в области). Это не тот случай, когда мы не знаем, к какому именно id-выражению можно отнести.

Кроме того, вы предлагаете создавать двусмысленности. Что это значит:

int lhs;

template<class Lhs, class Rhs>
  decltype(lhs+rhs) adding_func(const Lhs &lhs, const Rhs &rhs);

Является ли синтаксис decltype ссылкой на глобальную переменную lhs или локальный параметр функции lhs?

Как мы это делаем, есть четкое разграничение между этими двумя:

int lhs;
float rhs;

template<class Lhs, class Rhs>
  decltype(lhs+rhs) adding_func1(const Lhs &lhs, const Rhs &rhs);
template<class Lhs, class Rhs>
  auto adding_func2(const Lhs &lhs, const Rhs &rhs) -> decltype(lhs+rhs);

adding_func1 относится к глобальным переменным. adding_func2 относится к параметру функции.

Таким образом, вы можете радикально разбить каждый компилятор на С++ на поверхности Земли. Или вы можете просто указать свой тип возврата.

Или вы можете использовать подход С++ 14 и не беспокоить, чтобы указать его вообще.

Ответ 2

Ну, одна очевидная проблема заключается в том, что она откроет вас до циклов.

typedef decltype(lhs+lhs) foo;
foo lhs;