Для общего программирования на C++ характерно использование шаблонных параметров для представления абстрактных типов данных (или «понятий»). Тем не менее, сам язык C++ не обеспечивает механизм для автора шаблона класса или функции, чтобы явно заявить концепцию, что аргумент шаблона, предоставленный пользователем, должен моделировать (или соответствовать). Параметры шаблонов обычно называют в честь концепции, которую они должны моделировать как подсказку пользователю, и сделать требования к концепции явными в коде. Однако компилятор не рассматривает эти специальные имена специально: параметр, названный<RandomAccessIterator>, ничем не отличается от компилятора, чем один названный.<T>. Кроме того,
Сообщения об ошибках компилятора, возникающие в результате неправильных аргументов шаблона, особенно трудно расшифровать. Часто ошибка не указывает на местоположение сайта вызова шаблона, а вместо этого раскрывает внутренности шаблона, которые пользователь никогда не должен видеть.
Без проверки со стороны компилятора документированные требования часто бывают расплывчатыми, неправильными или несуществующими, поэтому пользователь не может точно знать, какие аргументы ожидаются.
Задокументированные требования к концепции могут не полностью охватыватьпотребности фактического шаблона, что означает, что пользователь может получить ошибку компилятора, даже если представленные аргументы шаблона соответствуют документированным требованиям.
Задокументированные требования к концепции могут быть слишком строгими, требующими большего, чем требуется шаблону.
Имена понятий в коде могут не совпадать с документированными требованиями.
Библиотека проверки концепции Boost предоставляет:
, , , , , , , , , , , , , , , , , , , , , .
Рамки, санитарно-эпидемиологические работы.
, , , , , , , , , , , , , , , .
«Блю-класс» — «Значение» и «класс архетипа», «граница» — «Стандартная система C++».
Механизмы используют стандартный C++ и не предусматривают накладных расходов на время выполнения. Основная стоимость использования механизма заключается в компиляции времени.Механизм вставки проверок времени компиляции по параметрам шаблона в точке их использования.
Структура для определения требований к концепции через классы проверки концепции.
Механизм проверки того, что требования к концепции охватывают шаблон.
Набор классов проверки концепции и классов архетипа, которые соответствуют требованиям концепции в стандартной библиотеке C++.
Альтернатива использованию классов признаков для доступа к связанным типам, которые отражают синтаксис, предложенный для следующего стандарта C++.
The mechanisms use standard C++ and introduce no run-time overhead.
The main cost of using the mechanism is in compile-time.[ORIG_END] -->
Каждый программист, пишущий класс или шаблоны функций, должен сделать проверку концепции нормальной частью своей рутины написания кода.Для каждого параметра шаблона в общедоступном интерфейсе компонента должна быть вставлена проверка концепции. Если концепция является одной из тех, что из Стандартной библиотеки, то просто используйте соответствующий класс проверки концепции в BCCL. Если нет, то напишите новый концепт контрольного класса — ведь они обычно всего несколько строк длиной. Для новых концепций также должен быть создан соответствующий класс архетипов, что является минимальной скелетной реализацией концепции.
Джереми Сиксоздал эту библиотеку.Беман Доузруководил официальным обзором.Дэйв Абрахамспереписал обновленный синтаксис, чтобы он был более совместим с предлагаемым синтаксисом для поддержки концепции основного языка C++.
Концепцияпредставляет собой набор требований (действительные выражения, ассоциированные типы, семантические инварианты, гарантии сложности и т.д.), которые тип должен выполнять, чтобы правильно использоваться в качестве аргументов в вызове к общему алгоритму. В C++ понятия представлены формальными параметрами шаблонов для функционирования шаблонов (общие алгоритмы). Однако C++ не имеет явного механизма представления понятий — параметры шаблонов являются просто заполнителями. Этим параметрам дают имена, соответствующие требуемой концепции, но компилятор C++ не обеспечивает соблюдение концепции, когда параметр шаблона привязан к фактическому типу.
Естественно, если общий алгоритм вызывается с типом, который не удовлетворяет, по крайней мере, синтаксическим требованиям концепции, возникает ошибка времени компиляции. Однако эта ошибка не будетсама по себеотражать тот факт, что тип не соответствовал всем требованиям концепции. Скорее, ошибка может произойти глубоко внутри иерархии инстанциации в точке, где выражение не является действительным для типа, или где предполагаемый ассоциированный тип недоступен. Полученные сообщения об ошибках в значительной степени неинформативны и в основном непроницаемы.
Требуется механизм обеспечения «безопасности концепции» в точке инстанциации (или вблизи нее). Библиотека проверки концепции Boost использует некоторые стандартные конструкции C++ для обеспечения соблюдения ранних концепций и предоставляет более информативные сообщения об ошибках при несоблюдении.
Обратите внимание, что этот метод касается только синтаксических требований понятий (действительных выражений и связанных типов). Мы не рассматриваем семантические инварианты или гарантии сложности, которые также являются частью требований концепции.
Приведем простой пример для иллюстрации неправильного использования библиотеки шаблонов и полученных сообщений об ошибках. В приведенном ниже коде общийstd::stable_sort()алгоритм из Стандартной библиотеки шаблонов (STL)3,4,5] применяется к связанному списку.
Попытка компиляции этого кода с помощью Gnu C++ приводит к следующей ошибке компилятора:
/usr/include/c++/4.1.2/bits/stl_algo.h: In function ‘void std::
__insertion_sort(_RandomAccessIterator, _RandomAccessIterator) [with
_RandomAccessIterator = __gnu_cxx::__normal_iterator<std::complex<float
>*, std::vector<std::complex<float>, std::allocator<std::complex<
float> > > >]’:
/usr/include/c++/4.1.2/bits/stl_algo.h:3066: instantiated from ‘void
std::__inplace_stable_sort(_RandomAccessIterator,
_RandomAccessIterator) [with _RandomAccessIterator = __gnu_cxx::
__normal_iterator<std::complex<float>*, std::vector<std::complex<
float>, std::allocator<std::complex<float> > > >]’
/usr/include/c++/4.1.2/bits/stl_algo.h:3776: instantiated from ‘void
std::stable_sort(_RandomAccessIterator, _RandomAccessIterator) [with
_RandomAccessIterator = __gnu_cxx::__normal_iterator<std::complex<float
>*, std::vector<std::complex<float>, std::allocator<std::complex<
float> > > >]’
bad_error_eg.cpp:8: instantiated from here
/usr/include/c++/4.1.2/bits/stl_algo.h:2277: error: no match for
‘operator<’ in ‘__val < __first. __gnu_cxx::__normal_iterator<
_Iterator, _Container>::operator* [with _Iterator = std::complex<float
>*, _Container = std::vector<std::complex<float>, std::allocator<
std::complex<float> > >]()’
В этом случае фундаментальная ошибка заключается в том, чтоstd:complexне моделирует концепциюLessThanComparable. К сожалению, в сообщении об ошибке нет ничего, что указывало бы на это пользователю.
Ошибка может быть очевидной для программиста C++, имеющего достаточный опыт работы с библиотеками шаблонов, но есть несколько причин, по которым это сообщение может быть трудно понять:
Нет никакой текстовой корреляции между сообщением об ошибке и документированными требованиями дляstd::stable_sort()и дляLessThanComparable.
Сообщение об ошибке слишком длинное, в нем перечислены внутренние функции STL (например,__insertion_sort), о которых пользователь не знает и не должен знать.
С таким количеством внутренних библиотечных функций, перечисленных в сообщении об ошибке, программист может легко сделать вывод, что проблема находится в библиотеке, а не в его или ее собственном коде.
Ниже приведен пример того, что мы можем ожидать от более информативного сообщения (и на самом деле это то, что производит Библиотека проверки концепции Boost):
boost/concept_check.hpp: In destructor ‘boost::LessThanComparable<TT>::~
LessThanComparable() [with TT = std::complex<float>]’:
boost/concept/detail/general.hpp:29: instantiated from ‘static void boost::
concepts::requirement<Model>::failed() [with Model = boost::
LessThanComparable<std::complex<float> >]’
boost/concept/requires.hpp:30: instantiated from ‘boost::_requires_<void
(*)(boost::LessThanComparable<std::complex<float> >)>’
bad_error_eg.cpp:8: instantiated from here
boost/concept_check.hpp:236: error: no match for ‘operator<’ in ‘((boost::
LessThanComparable<std::complex<float> >*)this)->boost::
LessThanComparable<std::complex<float> >::a < ((boost::
LessThanComparable<std::complex<float> >*)this)->boost::
LessThanComparable<std::complex<float> >::b’
Это сообщение устраняет некоторые недостатки стандартных сообщений об ошибках.
Сообщение явно относится к понятиям, которые пользователь может искать в документации STLLessThanComparable.
Сообщение об ошибке теперь намного короче и не раскрывает внутренних функций STL, и даже не указывает наstd::stable_sort.
Наличиеconcept_check.hppв сообщении об ошибке предупреждает пользователя о том, что ошибка лежит в коде пользователя, а не в реализации библиотеки.
Первая версия этой системы проверки была разработана Джереми Сиком во время работы в SGI в группе компиляторов и библиотек C++. Эта версия теперь является частью дистрибутива SGI STL. Система, первоначально введенная в качестве библиотеки проверки концепции ускорения, отличается от проверки концепции в SGI STL тем, что определение классов проверки концепции было значительно упрощено по цене менее полезного словосочетания в сообщениях об ошибках. В 2006 году система была переписана (сохранив обратную совместимость) Дэйвом Абрахамсом, чтобы быть более простой в использовании, более похожей на предлагаемую концепцию поддержки основного языка C++, и чтобы давать лучшие сообщения об ошибках.
Идея использовать указатели функций для инстанциации связана с Александром Степановым. Мы не уверены в происхождении идеи использовать выражения для предварительной проверки шаблонов, но она появилась в D&E2. Спасибо Мэтту Остерну за отличную документацию и организацию концепций STL, на которых основаны эти концептуальные проверки. Спасибо членам Boost за полезные комментарии и отзывы.
Статья Concept Check Library раздела может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.