Видимость вложенного вложенного класса C ++ в присутствии форвардных объявленийC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Видимость вложенного вложенного класса C ++ в присутствии форвардных объявлений

Сообщение Anonymous »

В C++ опережающие объявления представляют неполный тип. Неполные типы можно использовать для объявления указателей, но их нельзя использовать для инициализации значений или доступа к членам, поскольку полное определение не дано.
Это правило, очевидно, не распространяется на вложенные классы. Рассмотрим следующий рабочий пример:

Код: Выделить всё

struct C { // #1
// Forward declaration only
struct A; // #2
struct B {
// Pointer declaration is allowed with incomplete type
A* a;

int foo() {
// Member requires complete definition of A
return a->value;
}
};

// Complete definition of A given after B
struct A {
int value;
};

// Members and constructor
A a; B b;
C(int x) : a{x}, b{&a} {}
};

int main() {
C c{42};
return c.b.foo(); // returns 42
}
Этот фрагмент успешно компилируется с помощью g++ и clang. По-видимому, любая настройка приводит к сбою этой «предусмотрительной» ссылки на полное определение структуры A.
Дословное удаление определений A/B из включающей структуры C (т. е. удаление #1) приводит к ожидаемой ошибке о неправильном использовании неполного типа. Полное удаление предварительного объявления (т. е. удаление #2) приводит к ошибке «неизвестное имя типа «A».
Это не теоретическая проблема: библиотека Open Motion Planning Library, важная библиотека робототехники, использует этот шаблон в нескольких местах для определения компараторов для приоритетного порядка очереди. (Чтобы увидеть более полные примеры, найдите репозиторий MotionCompare).
Итак, вопрос: почему это компилируется? Это неясная стандартная функция вложенных типов или обычная ошибка компилятора? Изменилась ли достоверность этой конструкции по мере развития языкового стандарта?
РЕДАКТИРОВАТЬ: Этот связанный вопрос имеет аналогичный ответ, но это не тот же самый вопрос. В частности, эти двое не могли быть идентифицированы как дубликаты, не зная ответа. Этот вопрос касается явного предварительного объявления родственного класса; другой касается неявного предварительного объявления родительского класса. Тот факт, что в обеих ситуациях применяются одни и те же правила поиска имени, не был очевидным. Кроме того, поскольку другой вопрос явно не ссылается на предварительное объявление или родственные классы, маловероятно, что кто-то ищет ответ в этих случаях.

Подробнее здесь: https://stackoverflow.com/questions/797 ... forward-de
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»