синтаксический анализ порядка шаблонов c ++ / CRTP

Может кто-нибудь дать подсказку, как компилятор обрабатывает такие выражения, как

class DerivedA: public ParentTemplateClass<DerivedA>{
}

Для меня это выглядит так:

отец этого мальчика «сын» этого мальчика

Я имею в виду, что для меня не очевидно, как «разбор» класса DerivedA может быть завершен БЕЗ знания точного «описания» родительского класса. Кажется, это не может. Так что родительский класс должен обрабатываться раньше детей, но в такой ситуации родитель зависит от детей … и я застрял там.

Да, есть несколько статей в Интернете, которые описывают использование таких вещей, например, статья о шаблоне любопытно повторяющихся шаблонов (
http://en.wikibooks.org/wiki/More_C++_Idioms/Curiously_Recurring_Template_Pattern) но это не какой-то стандарт или что-то рядом. Должно быть четкое описание поведения, например порядок операций, не так ли?

ОТВЕТЫ:
Спасибо всем. Да, прямая аналогия с decl кажется мне законной, чтобы перестать повредить мой мозг. Шаблоны по-прежнему для меня современны из-за своей скрытой субъязыковой природы, и я не могу просто g ++ -E 🙂

5

Решение

После того, как ваш код говорит class DerivedA, символ DerviedA объявлен В данный момент его можно использовать в качестве параметра шаблона. Компиляторы C ++ выполняют несколько проходов кода, поэтому в этот момент при синтаксическом анализе компилятор «поверит», что ваше намерение было правильным и что он в конечном итоге получит определение этого класса (когда он собирается создать экземпляр шаблона, т.е. вы на самом деле используйте этот тип). Если нет, он будет жаловаться в этот момент. Подобное происходит, если вы использовали объявленный заранее класс в объявлении, но не предоставили определение перед его использованием.

6

Другие решения

В тот момент, когда создается экземпляр шаблона, DerivedA является неполный; это было объявленный, но не полностью определенный. Неполные типы можно использовать по-разному — например, вы можете объявить указатели или ссылки на них, объявить функции с ними как типы возвращаемых данных или параметров, и некоторые другие вещи. Вы не можете создавать объекты, наследовать их, получать доступ к их членам или вообще делать что-либо, что требует больше информации, чем просто имя класса.

Пока шаблон класса делает только эти вещи, проблем нет.

3

Я думаю, чтобы понять, как это может работать, вам нужно понимать больше о шаблонах C ++ в целом, чем просто шаблон Curiously Recurring Template Pattern. Кто-то другой может ответить на этот вопрос лучше меня, но я знаю, что C ++ не может полностью разобрать определение класса шаблона. Он создает шаблон каждый раз, когда он используется в коде. Если каждый класс был в отдельном включаемом файле, подумайте об этом так:

#include "ParentTemplateClass.h" // C++ initially validates the template class definition's syntax.
#include "DerivedA.h" // First use of ParentTemplateClass -
//   at this point it becomes fully instantiated.

Первоначально синтаксический анализатор C ++ проверяет синтаксис шаблона, когда видит определение шаблона. Затем, когда шаблон используется в качестве основы DerivedA, синтаксический анализ продолжается, и шаблон полностью создается. Это, конечно, упрощенный взгляд на синтаксический анализ, который будет выполнять компилятор C ++, и я уверен, что детали зависят от компилятора. Смотрите также http://womble.decadent.org.uk/c++/template-faq.html#disambiguation.

1
По вопросам рекламы [email protected]