Охватывают ли концепции STL все требования к аргументам для алгоритмов STL?

#c #algorithm #stl #c -concepts #callable-object

#c #алгоритм #stl #c -концепции #вызываемый объект

Вопрос:

Просматривая названия шаблонов некоторых алгоритмов,
я вижу, что название соответствует концепции библиотеки.

Возьмем, к примеру, std::mismatch.

 template< class InputIt1, class InputIt2, class BinaryPredicate >
std::pair<InputIt1,InputIt2>
mismatch( InputIt1 first1, InputIt1 last1,
          InputIt2 first2,
          BinaryPredicate p);
  

Требуется, BinaryPredicate который также является библиотечной концепцией.


Однако, глядя на другие алгоритмы, я вижу:

  • Неопределенный
  • Унарная функция
  • Безоперационная
  • Бинарная операция
  • и т. Д

и у них нет соответствующей концепции.

Есть ли причина, по которой они были исключены?
Можно ли вывести эти концепции путем объединения существующих концепций?

Комментарии:

1. cppreference документировал некоторые из них, а не другие. Я думаю, вы переоцениваете это.

2. UnaryPredicate по меньшей мере, похоже на синоним Predicate .

3. BinaryPredicate это название термина / типа, которое используется и определено в фактическом стандарте C (см. Раздел 25.1, параграф 9 этого проекта ). Однако термины UnaryPredicate и UnaryFunction никогда не встречаются в стандарте. BinaryOperation и UnaryOperation используются в стандарте, но не определены почти так явно, как BinaryPredicate .

Ответ №1:

Стандарт C не определяет «концепции». Он определяет «требования» как:

 EqualityComparable, LessThanComparable, DefaultConstructible,
MoveConstructible, CopyConstructible, MoveAssignable, CopyAssignable,
Destructible, NullablePointer, Hash, TrivialClock, Allocator,
Swappable or Container
  

Но некоторые требования используют синтаксис, отличный от других. Например, allocator и swappable используйте курсив в нижнем регистре (распределитель), а остальные из моего примера перечисляют моноширинный шрифт camelcase или, как описано в стандарте, константу с типом ( EqualityComparable ).

Другие «концепции», as PODType , рассматриваются в стандарте просто как определения.

Например, BinaryPredicate не определяется ни как концепция, ни как определение; просто как шаблонное имя функций, использующих его:

 void unique();
template <class BinaryPredicate> void unique(BinaryPredicate pred);
  

Эффекты: удаляет все, кроме первого элемента, из каждой последовательной группы равных элементов, на которые ссылаются
итератором, i находящимся в диапазоне, [first 1,last) для которого *i == *(i-1) (для версии без
аргументы) или pred(*i, *(i - 1)) (для версии с аргументом предиката) выполняется. Делает недействительным
только итераторы и ссылки на удаленные элементы.

Throws: Ничего, если исключение не генерируется сравнением равенства или предикатом.

Сложность: если диапазон [first,last) не пуст, то точно (last - first) - 1 применяются соответствующие предикаты, в противном случае предикат не применяется.

Как вы видите, BinaryPredicate не определено. Это просто показывает, как это влияет на поведение std::unique .

С другой стороны, список концепций cppreference извлекается из предложения concept, которое является нестандартным. Кроме того, cppreference не идеален, и не каждая страница wiki является полной или исчерпывающе описана с точки зрения концептуального предложения, и есть другие параметры шаблона, которые даже не отображаются в стандарте, например UnaryOperator .

Комментарии:

1. В списке Cppreference на этой странице указаны «именованные требования, используемые в нормативном тексте стандарта C «, а не те, которые указаны в предложении концепции (фактически диапазоны).