|
Программирование >> Полиморфизм без виртуальных функций в с++
Обе проблемы можно было бы смягчить, если ввести механизм, указывающий программисту, где сгенерировать определенные функции по шаблону с определенными аргументами. Это достаточно просто сделать в любой среде программирования. Тогда ошибки, относящиеся к конкретному определению шаблона функции, будут обнаруживаться в точке запроса. Неясно, однако, следует ли считать такой механизм частью языка или среды. Было решено, что необходимо накопить опыт, а пока - хотя бы на время - такие механизмы воспринимаются как часть среды. Простейший способ гарантировать правильную генерацию определений шаблонов функций - оставить решение на усмотрение программиста. Тогда компоновщик сообщит нужные определения, а файл, содержащий невстраиваемые определения шаблонов функций, можно будет откомпилировать, указав, какие будут использоваться аргументы шаблона. На базе такого подхода можно строить и более сложные системы . Теперь имеется множество разных реализаций. Практика показала, что сложность проблемы не была переоценена и что нынешние реализации не вполне удовлетворительны. В компиляторе Cfront [McCluskey, 1992] инстанцирование пиблонов автоматизировано, как и предполагалось в первоначальпо.м проекте [Stroustrup, 1988b] и в ARM. Принцип таков: запускается компоповшик, и если оказывается, что какой-то шаблон функции не инстанцирован, то снова вызывается компилятор, который генерирует отсутствующий объектный код. Этот процесс повторяется, пока не будут инстанцированы все шаблоны. Определения шаблонов и типов аргу.ментов (когда необходимо) базируются на соглашении.об именовании файлов. При необходимости вместе с таки.м соглашением можно использовать отдельный задаваемый пользователем файл, в котором имена шаблонов и классов ставятся в соответствие файла.м, где находятся их определения. У компилятора есть специальный режим для обработки инстанцировании шаблонов. Часто эта стратегия себя оправдывает, но в некоторых ситуациях возникают следующие проблемы: □ низкая производительность ко.мпиляции и компоновки. Если компоновщик определяет, что нужно инстанцирование, то приходится вызывать компилятор для генерирования необходимых функций. Затем компоновщик нужно вызвать С1юва. В системе, где компилятор и компоновщик не работают постоянноэто может оказаться очень накладно. Хороший механизм библиотек может существенно у.меньшить число запусков компилятора; □ плохая интеграция с система.ми контроля версий, имеющи.ми четко определенные представления о том, что такое исходный код, как из него получается объектный. Подобные систе.мы плохо взаимодействуют с системами разработки, в которых для получения полной программы сов.местно используются компилятор, компоновщик и библиотека (способ описан в первом пункте); □ слабое сокрытие деталей реализации. Если в реализации библиотеки используются шаблоны, то для того, чтобы пользователь мог скомпоновать свою программу с моей библиотекой, я должен предоставить исходные То есть не находятся в дисково.м кэше операционной системы. - Прим. перев. тексты шаблонов. Причина в то.м, что необходимость в инстанцирований шаблонов выявляется только на последнем этапе ко.мпоновки. Описанную проблему можно обойти, если заранее каким-то образом удастся сгенерировать объектный код, содержащий вес версии шаблонов, которые могут быть инстапцированы для моей библиотеки. В свою очередь, это .может привести к неоправданному увеличению объектного кода, если разработчик попытается предусмотреть все возможные способы использования, - а ведь в каждом конкретно.м приложении будет задействована лишь малая их часть. Отметим также, что, если инстанцирование пря.мо зависит от того, какие шаблоны пользователь инстанцирует, оно по необходимости должно быть поздним. 15.10.1. Явное инстанцирование Перспективным вариантом решения указанных проблем представляется необязательная возможность явного инстанцирования. Это мог бы быть внеязыко-вой .механизм, прагма компилятора или директива в самом языке. С те.м или иным успехом опробовались все эти способы. Меньше всего из них мне нравится ttpragma. Если уж нам нужен в языке механизм явного 1пгстанцирования, то он должен быть общедоступен и иметь четко определенную семантику. От необязательного оператора инстанцирования получи.м следующие преимущества: □ пользователю удастся задавать окружение для инстанцирования; □ он также сможет заранее создавать библиотеки наиболее часто инстанциру-емых шаблонов способом, мало зависящим от компилятора; □ предварительно созданные библиотеки будут зависеть не от изменений в среде программы, которая их использует, а только от контекста инстанцирования. Описанный здесь механизм инстанцирования по запросу одобрен на заседании комитета в Сан-Хосе; он основан на предложении Эрвина Унру (Erwin Unruh). Выбранный синтаксис соответствует тому, который используется при явном задании аргументов шаблона класса (см. раздел 15.3), вызовах шаблонов функций (см. раздел 15.6.2), в новых операторах приведения типов (см. разделы 14.2.2 и 4.3) и в специализациях шаблонов (см. раздел 15.10.3). Запрос на инстанцирование выглядит так: template class vector<int>; класс template int& vector<int>::operator[](int); член template int convert<int,double>(double); функция Было решено использовать уже имеющееся ключевое слово template, а не вводить новое - instantiate. Объявление шаблона отличается от запроса на инстанцирование по списку аргументов шаблона: определение шаблона начинается с template<, а запрос на инстанцирование - просто с template. Предпочтение было отдано полностью специфицированной, а не сокращенной форме вроде: не С++ template vector<int>::operator[]; член template convert<int,double>; функция Данное решение позволяет избежать неоднозначностей для перегруженных шаблонов функций и дает компилятору некоторую избыточную информацию, чтобы он мог выполнить проверки на непротиворечивость. Кроме того, запросы на инстанцирование встречаются достаточно редко, так что излишне лаконичная запись не очень нужна. Однако при вызовах шаблонов функций можно опускать аргументы шаблона, которые выводятся из фактических параметров функции (см. раздел 15.6.1). Например: template int convert<int>(double); функция Если шаблон класса инстанцируется явно, то инстанцируется и каждая его функция-член (см. раздел 15.10.4). Отсюда следует, что явное инстанцирование можно использовать для проверки ограничений (см. раздел 15.4.2). Инстанцирование по запросу позволяет существенно снизить время компоновки и число повторных компиляций. Есть примеры, когда перемещение всех инстанцировании шаблонов в одну единицу трансляции сокращают время сборки программы с нескольких часов до нескольких минут. Ради такого ускорения можно принять механизм оптимизации вручную. Что должно происходить, когда шаблон дважды явно инстанцируется с одним и тем же набором аргументов? (Вопрос считался фундаментальным.) Если воспринимать это как безусловную ошибку, то явное инстанцирование становится серьезным препятствием на пути сборки программ из независимо разработанных частей. Именно это и послужило первоначальным доводом против включения оператора явного инстанцирования. С другой стороны, подавление лишнего явного инстанцирования в обычной ситуации может оказаться очень трудной задачей. По вышеуказанному вопросу комитет решил дать свободу разработчикам компиляторов: множественное инстанцирование диагностировать необязательно. Это позволяет сложному компилятору игнорировать лишние инстанцирования и тем самым решить вышеупомянутую проблему составления программы из библиотечных модулей. Однако компилятор не всегда бывает настолько умным . Пользователи более простых компиляторов должны самостоятельно избегать множественного инстанцирования, но даже в самом худшем случае программа просто не будет загружаться; незаметно для пользователя семантика не изменится. Как и раньше, язык не требует инстанцировать шаблон явно. Явное инстанцирование - всего лишь оптимизация процесса компиляции и компоновки вручную. 15.10.2. Точка инстанцирования Самый трудный аспект определения шаблонов - точное указание, к каким объявлениям относятся имена, использованные в определении шаблона. Часто это называют проблемой привязки имен. Описываемые здесь пересмотренные правила привязки имен - плод многолетнего труда разработчиков, в особенности членов рабочей группы по расширениям -
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |