В качестве примера того, как создать шаблон класса проверки концепции, мы рассмотрим, как создать соответствующие проверки для концепцииInputIterator. Полное определение здесь:
template <class X>
struct InputIterator
: Assignable<X>, EqualityComparable<X>
{
private:
typedef std::iterator_traits<X> t;
public:
typedef typename t::value_type value_type;
typedef typename t::difference_type difference_type;
typedef typename t::reference reference;
typedef typename t::pointer pointer;
typedef typename t::iterator_category iterator_category;
BOOST_CONCEPT_ASSERT((SignedInteger<difference_type>));
BOOST_CONCEPT_ASSERT((Convertible<iterator_category, std::input_iterator_tag>));
BOOST_CONCEPT_USAGE(InputIterator)
{
X j(i); // require copy construction
same_type(*i++,v); // require postincrement-dereference returning value_type
X& x = ++j; // require preincrement returning X&
}
private:
X i;
value_type v;
// Type deduction will fail unless the arguments have the same type.
template <typename T>
void same_type(T const&, T const&);
};
Walkthrough
Во-первых, в качестве конвенции мы называем класс проверки концепции. Далее, поскольку InputIterator является усовершенствованием Assignable и EqualityComparable, мы выводим его класс проверки концепции из классов проверки для этих других концепций. Библиотека автоматически проверяет соответствие требованиям Assignable и EqualityComparable при проверке концепции InputIterator.
Далее мы объявляемассоциированные типыв качестве типовых членов. Связанный тип разности должен быть подписанным целым числом, а категория итератора должна быть конвертируемой в std::input_iterator_tag, поэтому мы утверждаем эти отношения. Синтаксис для доступа к связанным типам через шаблон проверки концепции отражаетпредложенныйсинтаксис для связанного доступа типа в C++0x Наконец, мы используем макрос<BOOST_CONCEPT_USAGE>, чтобы объявить функцию, которая выполняет все действительные выражения понятия. Обратите внимание, что в этот момент вам иногда может понадобиться немного творчески: например, чтобы проверить, что<*i++>возвращает тип значения итератора, мы передаем оба значения шаблону<same_type>функции члена, который требует, чтобы оба аргумента имели один и тот же тип, ссылки на модули и квалификацию cv. Это несовершенная проверка, но лучше, чем ничего.
Values for Usage Patterns Should Be Data Members
Вы можете задаться вопросом, почему мы объявили<i>и<v>участниками данных в примере выше. Почему мы просто не написали следующее?
BOOST_CONCEPT_USAGE(InputIterator)
{
X i; // create the values we need
value_type v;
X j(i); // require copy construction
same_type(*i++,v); // require postincrement-dereference returning value_type
X& x = ++j; // require preincrement returning X&
}
К сожалению, этот код не сработал бы так хорошо, потому что он непреднамеренно налагает требование о том, что<X>и его тип значений могут быть построены по умолчанию. С другой стороны, поскольку экземпляры шаблона<InputIterator>никогда не будут построены, компилятор никогда не должен проверять, как будут построены его члены данных (C++ Standard Section 14.7.1 9). По этой причине вы должнывсегда объявлять значения, необходимые для шаблонов использования в качестве членов данных.
Подобные ошибки в определениях понятий можно обнаружить с помощьюАрхетипов понятий, но всегда лучше избегать их превентивно.
Similarity to Proposed C++0x Language Support for Concepts
Синтаксисы этой библиотеки для уточнения концепции и для доступа к связанным типам отражают соответствующиепредложенныесинтаксисы в C++0x. Тем не менее, C++0x будет использовать «подписи», а не шаблоны использования для описания действительных операций над типами, участвующими в концепции, поэтому при преобразовании классов проверки концепции в поддерживаемые языком концепции вам нужно будет перевести функцию использования в серию подписей.
Статья Creating Concept Checking Classes раздела может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.