Объявление главного друга считается вредным?

Обсуждение

Я знаю, что main может быть другом class:

#include <iostream>

class foo {
  friend int main();
  int i = 4;
};

int main() {
  foo obj;
  std::cout << obj.i << std::endl;
}

LIVE DEMO

Однако я чувствую, что, хотя это вполне допустимо, он скрывает множество опасностей.

Вопросы

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

Ответы

Ответ 1

Выбор, использовать или избегать юридической функции, становится спорным, если функция не является, по сути, законной. Я считаю, что в этом есть серьезные сомнения, потому что в Стандарте говорится

Функция main не должна использоваться в программе.

Уже существует вопрос о том, разрешено ли поддерживать ::main(), и вы найдете более подробную информацию в моем ответе там.

Ответ 2

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


Однако я вижу одну возможную опасность:

Стандарт С++:

  • Раздел § 11.3 (Друзья)

Функция, объявленная в объявлении друга, имеет внешнюю привязку

  • Раздел § 3.6.1 (Основная функция)

Связывание основного определяется реализацией

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

Ответ 3

Бен уже указал, что проект стандарта С++ в разделе 3.6.1 Основная функция говорит:

Функция main не должна использоваться внутри программы. [...]

но используемый термин не определен, и поэтому неясно, какова должна быть интерпретация. К счастью для нас, мы можем найти две свидетельства вне SO, которые сильно указывают на то, что любое использование main плохо сформировано.

Сначала мы обсудим этот раздел в undefined обзоре по группам исследований поведения в потоке Что означает "функция main не должна использоваться в программе" означает?, эта цитата из здесь кажется подвести итог:

У С++ 98 упоминание "use" имело перекрестную ссылку на 3.2 [basic.def.odr]. С++ 11 больше не имеет перекрестной ссылки и не был изменен, чтобы сказать "odr-use", поэтому я ожидаю, что это означает любое использование.

у нас есть дополнительные доказательства из исходного предложения: N3154, чтобы исправить Отчет о дефектах 1109 изменил бы 3.6.1 на:

Функция main не должна использоваться в качестве параметра (3.2) в программе....

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

Функция main не должна использоваться в программе