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

Ответ не ясен С++

Вот тестовый вопрос:

Рассмотрим следующий код:

class A {
    typedef int I; // private member
    I f();
    friend I g(I);
    static I x;
};

Какое из следующего допустимо:

a. A::I A::f() { return 0; }
b. A::I g(A::I p = A::x);
c. A::I g(A::I p) { return 0; }
d. A::I A::x = 0;

Ответ на этот вопрос считается правильным только для первой версии (а.), но почему? Все они действительны, на мой взгляд. Даже проверены все они компилируются успешно. Почему правильный ответ правильный?

4b9b3361

Ответ 1

Тот, кто написал исходный ответ на тест, ошибочен.

  • Этот пример приходит (точно) из самого стандарта С++, раздел § 11/7, [class.access] и был скопирован тем, кто написал "тест"

Пример идет еще дальше в стандарте, с шаблонами (я опускаю их здесь):

      class A {
          typedef int I;      // private member
          I f();
          friend I g(I);
          static I x;
      };

      A::I A::f() { return 0; }
      A::I g(A::I p = A::x);
      A::I g(A::I p) { return 0; }
      A::I A::x = 0;
  • Указание стандарта для объяснения:

Здесь все использование A::I хорошо сформировано, потому что A::f и A::x являются члены класса A и g являются друзьями класса A. Это означает, что для Например, проверка доступа при первом использовании A::I должна быть откладывается до тех пор, пока не будет определено, что это использование A::I является возвратом тип члена класса A.]

Ответ 2

Все они действительны для С++.

Вот точный код, это пример из самого стандарта:

http://www.open-std.org/jtc1/sc22/open/n2356/access.html

Вот как я их разбираю:

a. A::I A::f() { return 0; } // defines A::f() which was previously prototyped

b. A::I g(A::I p = A::x);    // declares prototype g(A::I), but doesn't define it

c. A::I g(A::I p) { return 0; } // defines g(A::I)

d. A::I A::x = 0; // defines static storage for A::x which was previously declared in A

Все они компилируются, как индивидуально, так и коллективно.