Этот допустимый код C++?

, Если бы я запустил свой очень собственный главный проект программного обеспечения теперь, я принял бы свое решение языка на основе критериев выше. Несомненно, я люблю Lisp, CLOS является потрясающими, реальными лексическими скалами обзора, макросы Lisp прохладный путь (когда используется, как направлено), и лично мне действительно нравится синтаксис Lisp. [†¦], Но это взяло бы много или потребовало бы особых обстоятельств, чтобы убедить меня выбрать Lisp для главного проекта программного обеспечения, если бы я ответил за совершение выбора. - Dan Weinreb

23
задан MikeT 12 August 2009 в 16:01
поделиться

4 ответа

Если я правильно прочитал стандарт, g ++ верен, а VS - нет.

ISO-IEC 14882-2003 (E), §9.2 Классы (pag.153) : Имя класса вставляется в область видимости, в которой оно объявлено, сразу после того, как будет обнаружено имя класса. Имя класса также вставляется в область видимости самого класса; это известно как внедренное имя-класса. В целях проверки доступа внедренное имя-класса обрабатывается так, как если бы оно было открытым именем члена.

Следуя комментариям ниже, также особенно полезно сохранить следующее, касающееся фактических правил поиска имени:

ИСО-МЭК 14882-2003 (E), §3.4-3 Поиск имени (стр.29) : Введенное имя класса класса (пункт 9) также считается членом этого класс для скрытия имени и поиска.

Было бы странно, если бы это было не так, учитывая последнюю часть текста в 9.2. Но, как прокомментировал литб, это убеждает нас в том, что действительно g ++ правильно интерпретирует стандарт. Не осталось вопросов.

25
ответ дан 29 November 2019 в 02:16
поделиться

Есть ли пространство имен foo в каком-то другом модуле, который вы включаете (а вы просто не знали о нем)? В противном случае это неверно. Я не уверен, почему g ++ это допускает.

0
ответ дан 29 November 2019 в 02:16
поделиться

Кругар дает здесь правильный ответ. Имя, которое обнаруживается каждый раз, является именем внедренного класса.

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

namespace NS
{
  class B
  {
  // injected name B    // #1
  public:
    void foo ();
  };

  int i;                // #2
}

class B                 // #3
{
public:
  void foo ();
};


int i;                  // #4

class A :: NS::B
{
public:
  void bar ()
  {
    ++i;           // Lookup for 'i' searches scope of
                   // 'A', then in base 'NS::B' and
                   // finally in '::'.  Finds #4

    B & b = *this; // Lookup for 'B' searches scope of 'A'
                   // then in base 'NS::B' and finds #1
                   // the injected name 'B'.

  }
};

Без введенного имени текущие правила поиска будут в конечном итоге достигнет охватывающей области «A» и найдет «:: B», а не «NS :: B». Поэтому нам нужно будет использовать «NS :: B» везде в A, когда мы хотим ссылаться на базовый класс.

Еще одно место, где используются внедренные имена, - это шаблоны, где внутри шаблона класса внедренное имя обеспечивает соответствие между именем шаблона и типом:

template <typename T>
class A
{
// First injected name 'A<T>'
// Additional injected name 'A' maps to 'A<T>'

public:
  void foo ()
  {
    // '::A' here is the template name
    // 'A' is the type 'A<T>'
    // 'A<T>' is also the type 'A<T>'
  }
};
11
ответ дан 29 November 2019 в 02:16
поделиться

Comeau online принимает его без каких-либо проблем, так что это либо действительный, либо вторая ошибка в como, которую я обнаружил почти за десять лет.

1
ответ дан 29 November 2019 в 02:16
поделиться
Другие вопросы по тегам:

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