Следует ли избегать main с завершающим возвращаемым типом?

В приведенном ниже примере кода функция main написана с нотацией замыкающего возвращаемого типа C++11:

auto main() -> int {
  //...
  return 0;
}

Вопрос:

Есть ли причины, по которым следует избегать main с конечным типом возврата и предпочесть классическую нотацию?


person 101010    schedule 27.06.2014    source источник
comment
Интересный вопрос, а есть ли в этом практическая необходимость? Не могу придумать минусов, но и практического применения тоже не вижу ;-)   -  person anderas    schedule 27.06.2014
comment
int main() быть короче было бы одной из причин, чтобы предпочесть его. Кроме того, (хотя и не связанный) return 0; можно опустить вместо main.   -  person Michael    schedule 27.06.2014
comment
Почему вы ожидаете, что этот вопрос будет лучше? Мое личное мнение по этому поводу состоит в том, что мы все приучены подсознательно сопоставлять шаблоны int main() как нечто безобидное. Но всякий раз, когда я вижу auto main() -> int, это заставляет меня взглянуть на него еще раз, хотя бы подумать, как глупо, прежде чем двигаться дальше.   -  person Praetorian    schedule 27.06.2014
comment
Еще лучше auto main() -> void ШУТКА   -  person Neil Kirk    schedule 27.06.2014
comment
@Praetorian Причина в том, что, когда я опубликовал живую демонстрацию с новой нотацией, меня раскритиковали многие, которые считали, что использование завершающих типов возврата без конкретной причины - или не как часть определенной техники приводит к ухудшениям. Пожалуйста, я хотел бы, чтобы кое-что прояснилось по этому поводу.   -  person 101010    schedule 27.06.2014
comment
@ 40two Я помню комментарий XML от Керрека :). Очевидно, в этом нет ничего плохого, но это больше нажатий клавиш по сравнению со старым синтаксисом. Используйте его, если это то, что вам кажется подходящим.   -  person Praetorian    schedule 27.06.2014
comment
@Praetorian действительно не обижается на Керрека :) Я очень уважаю этого парня. Мне очень понравилась шутка :).   -  person 101010    schedule 27.06.2014
comment
Я почти уверен, что это выглядит круто, это единственное, что есть в этой форме. Однако значение этого выглядит круто никогда не следует недооценивать.   -  person Galik    schedule 27.11.2014


Ответы (3)


Это совершенно правильно и работает просто отлично.

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

Но это работает, поэтому не стесняйтесь писать свой main таким образом, если вам так хочется.

person jalf    schedule 27.06.2014
comment
Возможная проблема, которую следует упомянуть, заключается в том, что некоторые инструменты документации (или статического анализа) еще не поддерживают новый стиль возвращаемого типа (они должны, как и другие новые функции С++, действительно) - person quantdev; 27.06.2014

Во-первых, давайте посмотрим, почему вам следует использовать конечные возвращаемые типы вообще.

Комментарий Kerrek SB к вашему предыдущему вопросу:

Конечные возвращаемые типы — это специализированная функция языка, которая в основном полезна для составителей универсальных библиотек (то есть авторов универсальных библиотек, а не универсальных личностей, которые пишут библиотеки), подобно decltype. Между прочим, обе функции языка также имеют ограниченное применение в непонятных или длинных лямбда-выражениях, но их не следует часто использовать в обычном пользовательском коде.

Из ответа Дитмара Кюля (который вы указали в своем предыдущем вопросе, поэтому вы должны были его прочитать):

Значимость завершающих типов возвращаемых значений в первую очередь связана с шаблоном функции, где теперь можно использовать параметры функции вместе с decltype() для определения типа возвращаемого значения. Например:

template <typename M, typename N>
auto multiply(M const& m, N const& n) -> decltype(m * n);

Это объявляет функцию multiply() возвращающей тип, созданный m * n. Использование decltype() перед multiply() было бы недопустимым, поскольку m и n еще не объявлены.

Я считаю и Керрека С.Б., и Дитмара Кюля экспертами по C++ и нахожу их рекомендации хорошими. Теперь давайте посмотрим, как приведенные выше рекомендации применимы к int main(). Некоторые наблюдения:

  • int main() не является шаблоном функции.
  • Вывод типа не происходит.
  • Тип возвращаемого значения (int) не изменится в обозримом будущем; мы можем безопасно зафиксировать этот тип.

Есть ли какие-либо причины, по которым следует избегать main с конечным возвращаемым типом и предпочесть классическую нотацию?

Да:

  1. Это сбивает с толку тех разработчиков, которые не знакомы с новым синтаксисом.

  2. Не все инструменты поддерживают эту новую языковую функцию.

  3. Как обсуждалось выше, использование этой функции необязательно с int main().

Я считаю так.

person Ali    schedule 27.06.2014
comment
Прежде всего, спасибо, что нашли время ответить. Из вашего ответа я могу сделать вывод, что использование новой нотации не приводит к каким-либо практическим ухудшениям, а скорее касается практических вопросов, таких как читаемость кода и незнание персонала разработчиков. Пожалуйста, позвольте мне не рассматривать обратную совместимость как проблему, поскольку это относится почти ко всем новым функциям, представленным в C++11. P.S. Я очень уважаю обоих джентльменов, которых вы упомянули, мое единственное намерение — учиться, и я многому у них учусь :). - person 101010; 28.06.2014

Это просто глупо.

Нет никакой выгоды, нет необходимости или причины писать что-то подобное.

Чтобы быть педантичным, вы добавляете символы auto и -> без всякой причины.

Завершающий тип возвращаемого значения обычно используется для вывода типа возвращаемого значения после введения аргументов функции. Здесь вы уже знаете тип возврата.

Можете ли вы представить (внешний вид) своей кодовой базы, если бы все ваши функции использовали эту нотацию без необходимости в этом? Вы бы практически оставили на переднем плане все спецификации хранилища, likage, static и т. д., а тип возвращаемого значения оставили бы в конце, чтобы смешать его со спецификациями исключений, спецификаторами const и т. д.?


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

Беззаботные сдвиги в норме являются признаками нестабильности и недостатка общения. Такая функция, как Python PEP8, была бы хорошей Вещь иметь и натренированные глаза следует отбрасывать с осторожностью.

person Nikos Athanasiou    schedule 27.06.2014
comment
Я думаю, что разумно всегда использовать завершающий тип возвращаемого значения для каждой функции для согласованности. Кроме того, что я печатаю больше, я не вижу никаких недостатков. - person Neil Kirk; 27.06.2014
comment
Можете ли вы представить свою кодовую базу, если бы все ваши функции использовали эту нотацию без необходимости делать это? Да, я могу. Синтаксически это намного ближе к тому, как хорошо спроектированные языки выражают типы функций. - person jalf; 27.06.2014
comment
Таким образом, вы бы практически оставили все хранилище, спецификации likage, статические и т. д. и оставили тип возвращаемого значения в конце, чтобы смешаться со спецификациями исключений, спецификаторами const и прочими? О, какая кодовая база... - person Nikos Athanasiou; 27.06.2014
comment
Можете ли вы представить (внешний вид) вашей кодовой базы — действительно могу. Читать было бы чуть приятнее (особенно при возврате сложного типа), но не такое массовое улучшение, чтобы спорить об этом с теми, кто предпочитает старый стиль. - person Mike Seymour; 27.06.2014
comment
чтобы смешиваться со спецификациями исключений, спецификаторами const и другими — спецификаторы идут перед ->, а friend идут в начале (смешиваясь с возвращаемым типом старой школы). Ничто не смешивается с конечным возвращаемым типом. - person Mike Seymour; 27.06.2014
comment
@NikosAthanasiou Я предлагаю вам посмотреть, как функции выражаются в математике. И в функциональных языках программирования. Или, по сути, везде за пределами семейства языков C. И я бы хотел, чтобы вы объяснили, почему было бы ужасно помещать возвращаемый тип в конец. Почему это плохо, если он смешивается со спецификациями исключений, спецификаторами const и прочими подобными? - person jalf; 27.06.2014
comment
Был один аргумент, что имена ваших функций хорошо выстраиваются в линию, если они тоже по одному в строке. Я думаю, что он довольно хорошо работает с синтаксисом автоматического вывода типа возврата С++ 14. В этом случае конечный тип просто опускается. Например. На самом деле, было бы интересно увидеть обсуждение этого стиля на CppCon. - person chris; 27.06.2014
comment
@jalf мой ответ находится в редактировании - person Nikos Athanasiou; 27.06.2014
comment
На самом деле, одна из причин сделать это таким образом состоит в том, чтобы уменьшить количество стилей/функций, присутствующих в вашем коде, всегда используя завершающий возврат (и упростить переключение на вывод C++14, когда он прибывает) - person Joe; 27.06.2014
comment
Вы действительно высказали свою точку зрения :), хотя нет реальной причины использовать расплывчатые выражения для этого. Но я должен признать, что ваши аргументы весомы. Меня также очень беспокоит потенциальная фрагментация языка. Выполнение одного действия многими способами может привести к двусмысленности, что не очень хорошо. Я действительно думаю, что сообщество должно обсудить этот вопрос. - person 101010; 28.06.2014