Я хочу знать, каковы семантические различия между полным предложением концепций C ++ и шаблонными ограничениями (например, ограничениями, которые появились в Dlang или новое концептуально-облегченное предложение для C ++ 1y).
На что способны полноценные концепции, на которые не способны ограничения шаблона?
Следующая информация устарела. Он должен быть обновлен в соответствии с последним проектом Concepts Lite.
Раздел 3 предложение об ограничениях охватывает это в разумной глубине.
Концепции предложения ненадолго был отложен на задний план в надежде, что ограничения (т. е. концептуальные) могут быть устранены и реализованы в более короткие сроки, в настоящее время нацеленные на достижение чего-то в C ++ 14. Предложение об ограничениях предназначено для плавного перехода к более позднему определению понятий. Ограничения часть Концепции предложения и являются необходимым строительным блоком в его определении.
В Разработка концептуальных библиотек для C ++, Саттон и Страуструп рассматривают следующие отношения:
Концепции = Ограничения + Аксиомы
Чтобы быстро суммировать их значения:
Поэтому, если вы добавите аксиомы (семантические свойства) в ограничения (синтаксические свойства), вы получите концепции.
Предложение о концептуальном подходе приносит нам только первую часть, ограничения, но это важный и необходимый шаг на пути к полноценным концепциям.
Ограничения все о синтаксис. Они дают нам способ статически различать свойства типа во время компиляции, чтобы мы могли ограничивать типы, используемые в качестве аргументов шаблона, на основе их синтаксических свойств. В текущем предложении об ограничениях они выражаются подмножеством исчисления высказываний с использованием логических связок, таких как &&
а также ||
,
Давайте посмотрим на ограничение в действии:
template <typename Cont>
requires Sortable<Cont>()
void sort(Cont& container);
Здесь мы определяем шаблон функции с именем sort
, Новое дополнение является требует оговорки. Предложение require дает некоторые ограничения на аргументы шаблона для этой функции. В частности, это ограничение говорит о том, что тип Cont
должен быть Sortable
тип. Замечательно то, что это можно записать в более сжатой форме как:
template <Sortable Cont>
void sort(Cont& container);
Теперь, если вы попытаетесь передать что-то, что не считается Sortable
с этой функцией вы получите приятную ошибку, которая сразу скажет вам, что тип, выведенный для T
это не Sortable
тип. Если бы вы сделали это в C ++ 11, вы бы получили ужасную ошибку из внутри sort
функция, которая не имеет смысла ни для кого.
Предикаты ограничений очень похожи на черты типа. Они принимают некоторый тип аргумента шаблона и дают вам некоторую информацию об этом. Ограничения пытаются ответить на следующие вопросы о типе:
Однако ограничения не предназначены для замещать Тип черт. Вместо этого они будут работать рука об руку. Некоторые черты типа теперь могут быть определены с точки зрения понятий, а некоторые понятия с точки зрения черт типа.
Таким образом, важная вещь об ограничениях состоит в том, что они не заботятся о семантике ни на йоту. Вот несколько хороших примеров ограничений:
Equality_comparable<T>
: Проверяет, есть ли у типа ==
с обоими операндами того же типа.
Equality_comparable<T,U>
: Проверяет, есть ли ==
с левым и правым операндами данных типов
Arithmetic<T>
: Проверяет, является ли тип арифметическим типом.
Floating_point<T>
: Проверяет, является ли тип типом с плавающей запятой.
Input_iterator<T>
: Проверяет, поддерживает ли тип синтаксические операции, которые должен поддерживать входной итератор.
Same<T,U>
: Проверяет, является ли данный тип одинаковым.
Вы можете попробовать все это с помощью специального концептуально-облегченная сборка GCC.
Теперь мы переходим ко всему, что выходит за рамки концептуального предложения. Это даже более футуристично, чем само будущее. С этого момента все может измениться совсем немного.
Аксиомы все о семантика. Они определяют отношения, инварианты, гарантии сложности и другие подобные вещи. Давайте посмотрим на пример.
В то время как Equality_comparable<T,U>
ограничение скажет вам, что есть operator==
что принимает типы T
а также U
, это не говорит вам, что это за операция средства. Для этого у нас будет аксиома Equivalence_relation
, Эта аксиома говорит о том, что когда объекты этих двух типов сравниваются с operator==
дающий true
эти объекты эквивалентны. Это может показаться излишним, но это, безусловно, нет. Вы можете легко определить operator==
что вместо этого вел себя как operator<
, Вы были бы злы, чтобы сделать это, но вы могли бы.
Другой пример Greater
аксиома. Это все хорошо и хорошо, чтобы сказать два объекта типа T
можно сравнить с >
а также <
операторы, но что они имею в виду? Greater
Аксиома говорит, что если x
больше, чем y
, затем y
меньше чем x
, В предлагаемой спецификации такая аксиома выглядит так:
template<typename T>
axiom Greater(T x, T y) {
(x>y) == (y<x);
}
Таким образом, аксиомы отвечают на следующие типы вопросов:
То есть они полностью связаны с семантикой типов и операций над этими типами. Эти вещи не могут быть проверены статически. Если это необходимо проверить, тип должен каким-то образом объявить, что он придерживается этой семантики.
Вот несколько распространенных примеров аксиом:
Equivalence_relation
: Если сравниваются два объекта ==
они эквивалентны.
Greater
: Всякий раз, когда x > y
, затем y < x
,
Less_equal
: Всякий раз, когда x <= y
, затем !(y < x)
,
Copy_equality
: За x
а также y
типа T
: если x == y
новый объект того же типа, созданный копированием T{x} == y
И еще x == y
(то есть это неразрушающий).
Теперь понятия очень легко определить; они просто сочетание ограничений и аксиом. Они предоставляют абстрактное требование к синтаксису и семантике типа.
В качестве примера рассмотрим следующее Ordered
концепция:
concept Ordered<Regular T> {
requires constraint Less<T>;
requires axiom Strict_total_order<less<T>, T>;
requires axiom Greater<T>;
requires axiom Less_equal<T>;
requires axiom Greater_equal<T>;
}
Сначала обратите внимание, что для типа шаблона T
быть Ordered
он также должен соответствовать требованиям Regular
концепция. Regular
Понятие является очень основным требованием того, что тип хорошо себя ведет — его можно конструировать, уничтожать, копировать и сравнивать.
В дополнение к этим требованиям, Ordered
требует, чтобы T
встретить одно ограничение и четыре аксиомы:
Ordered
тип должен иметь operator<
, Это статически проверено, так что должен существовать.x
а также y
типа T
:
x < y
дает строгий общий порядок.x
больше, чем y
, y
меньше чем x
, и наоборот.x
меньше или равно y
, y
не менее чем x
, и наоборот.x
Больше или равно y
, y
не больше чем x
, и наоборот.Подобное сочетание ограничений и аксиом дает вам понятия. Они определяют синтаксические и семантические требования к абстрактным типам для использования с алгоритмами. Алгоритмы в настоящее время должны предполагать, что используемые типы будут поддерживать определенные операции и выражать определенную семантику. С концепциями, мы сможем обеспечить выполнение требований.
В новейшие концепции дизайна, компилятор будет проверять только то, что синтаксические требования концепции удовлетворяются аргументом шаблона. Аксиомы оставлены без проверки. Поскольку аксиомы обозначают семантику, которая не является статически оцениваемой (или часто не поддающейся полной проверке), автору типа придется явно заявить, что его тип соответствует всем требованиям концепции. Это было известно как отображение концепции в предыдущих проектах, но с тех пор было удалено.
Вот несколько примеров концепций:
Regular
типы являются конструируемыми, разрушаемыми, копируемыми и могут сравниваться.
Ordered
поддержка типов operator<
и имеют строгий порядок упорядочения и другую семантику упорядочения.
Copyable
типы являются копируемыми, разрушаемыми, и если x
равно y
а также x
копируется, копия также будет сравниваться равной y
,
Iterator
типы должны иметь связанные типы value_type
, reference
, difference_type
, а также iterator_category
которые сами должны соответствовать определенным понятиям. Они также должны поддерживать operator++
и быть разыменованным.
Ограничения являются первым шагом на пути к полной концепции понятий в C ++. Это очень важный шаг, потому что они обеспечивают статически обязательные требования типов, чтобы мы могли писать намного более чистые функции и классы шаблонов. Теперь мы можем избежать некоторых трудностей и уродства std::enable_if
и его метапрограммирующие друзья.
Однако есть несколько вещей, которые предложение по ограничениям не делает:
Это не обеспечивает язык определения понятия.
Ограничения не являются концептуальными картами. Пользователь не должен специально аннотировать свои типы как соответствующие определенным ограничениям. Они статически проверяются с использованием простых функций языка времени компиляции.
Реализации шаблонов не ограничены ограничениями их аргументов шаблона. То есть, если ваш шаблон функции делает что-либо с объектом ограниченного типа, чего он не должен делать, компилятор не может это диагностировать. Полнофункциональное концептуальное предложение сможет сделать это.
Предложение об ограничениях было разработано специально для того, чтобы поверх него можно было представить полное предложение концепций. Если повезет, этот переход должен быть довольно плавным. Группа концепций стремится ввести ограничения для C ++ 14 (или вскоре после этого в техническом отчете), в то время как полные концепции могут начать появляться где-то вокруг C ++ 17.
См. Также «Что такое« Lite »о концептах lite» в разделе 2.3 последних (12 марта) телеконференций и концепций обсуждения, которые были опубликованы в тот же день здесь: http://isocpp.org/blog/2013/03/new-paper-n3576-sg8-concepts-teleconference-minutes-2013-03-12-herb-sutter .
Мои 2 цента:
Концептуально-облегченное предложение не предназначено для «проверки типа» шаблона реализация. То есть, Concepts-lite обеспечит (условно) совместимость интерфейса на сайте создания шаблона. Цитата из статьи: «концепты lite — это расширение C ++, которое позволяет использовать предикаты для ограничения аргументов шаблона». И это все. Это не говорит о том, что тело шаблона будет проверено (изолированно) по отношению к предикатам. Это, вероятно, означает, что нет первоклассного понятия archtypes когда ты говоришь о понятиях-лайт. Архетипы, если я правильно помню, в концептуально-насыщенном предложении есть типы, которые предлагают не меньше и не больше, чтобы удовлетворить реализация шаблона.
concept-lite использует прославленные функции constexpr с небольшим синтаксическим трюком, поддерживаемым компилятором. Никаких изменений в правилах поиска.
Программисты не обязаны писать концептуальные карты.
И, наконец, еще раз процитируем: «Предложение об ограничениях не касается непосредственно спецификации или использования семантики; оно предназначено только для проверки синтаксиса». Это означало бы, что аксиомы не входят в сферу (пока).