Код ниже не компилируется.Возможно, потому что GCC с std = c ++ 2a все еще не полностью соответствует последнему проекту - PullRequest
0 голосов
/ 14 февраля 2019

[class.mem] / 6 :

A полный контекст класса класса представляет собой

(6.1) тело функции, (6.2) аргумент по умолчанию, (6.3) спецификатор noexcept ([exc.s.spec]), (6.4) условие контракта или (6.5) инициализатор члена по умолчанию

в пределах спецификация члена класса.[Примечание: контекст полного класса вложенного класса также является контекстом полного класса любого включающего класса, если вложенный класс определен в спецификации члена включающего класса.- примечание к концу]

Этот абзац был введен в черновик вместе с запросом на извлечение # 2231 .

Насколько я понимаю, следующий код долженскомпилируйте, согласно примечанию выше.Но это не .Я предполагаю, что компилятор GCC все еще не соответствует последней версии.Я прав или это мое понимание этой заметки неверно?

struct A {
    int i = 1;
    struct B { 
        int j = 2;
        int f() {
            return i + j;
        }
    };
};

Что не так:

source>: In member function 'int A::B::f()':
<source>:6:20: error: invalid use of non-static data member 'A::i'
    6 |             return i + j;
      |                    ^
<source>:2:9: note: declared here
    2 |     int i = 1;
      |         ^

Ответы [ 2 ]

0 голосов
/ 14 февраля 2019

Тогда что именно говорит эта заметка?

Имена, объявленные в классе A, находятся в области видимости в контексте полного класса, даже если до точки объявления имени.

Примечание означает, что контекст полного класса включающего класса (отмечая предварительное условие) распространяется на контекст полного класса вложенного класса.

Следовательно, правильная форма следующего:

struct A {
    struct B{
        void foo() {
            // names are in scope despite being before point of declaration
            I i;
            var;
        }
    };

     using I = int;
     static int var;
};

Вы не можете получить доступ к нестатическому члену данных в (нестатической) функции-члене другого класса, так же, как вы не можете получить доступ к нестатическому.статические члены в статической функции-члене того же класса.Контекст полного класса не меняет этого.

0 голосов
/ 14 февраля 2019

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

Важно, что поиск имени найдет там i,Таким образом, я могу написать это:

struct A {
    struct B { 
        int j = 2;
        int f() {
            using T = decltype(i); // ok, even though 'i' declared later lexically
            return T{} + j;        // ok
        }
    };
    int i = 1;
};

А также:

struct A {
    struct B { 
        int j = 2;
        int f() {
            return i + j; // ok, even though 'i' declared later lexically
        }
    };
    static const int i = 1;
};

Действительно, все это было хорошо в C ++ 11.

Ноi все еще нестатический член, поэтому вы можете получить к нему доступ только из контекста объекта типа A.В теле функции-члена B у нас неявно есть объект A.Так что такое бесплатное использование i все еще плохо сформировано.

Тем не менее, это:

Я предполагаю, что компилятор GCC все еще не соответствует последней версии.

Это, безусловно, правда, и останется верным еще довольно долго.

...