Концепция Проверка изменений в C ++? - PullRequest
2 голосов
/ 28 октября 2009

Я портирую некоторый код из одного проекта в другой в моей компании, и я столкнулся с общей функцией sets_intersect, которая не компилируется:

template<typename _InputIter1, typename _InputIter2, typename _Compare>
bool sets_intersect(_InputIter1 __first1, _InputIter1 __last1,
                    _InputIter2 __first2, _InputIter2 __last2,
                    _Compare __comp)
{
    // Standard library concept requirements
    // These statements confuse automatic indentation tools.
    // concept requirements
    __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
    __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
    __glibcpp_function_requires(_SameTypeConcept<
          typename iterator_traits<_InputIter1>::value_type,
          typename iterator_traits<_InputIter2>::value_type>)
    __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
          typename iterator_traits<_InputIter1>::value_type>)
    __glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
          typename iterator_traits<_InputIter1>::value_type,
          typename iterator_traits<_InputIter2>::value_type>)

    while (__first1 != __last1 && __first2 != __last2)
    if (__comp(*__first1, *__first2))
            ++__first1;
    else if (__comp(*__first2, *__first1))
            ++__first2;
    else {
            return true;
    }
    return false;
}

Я новичок в этой концепции "концепций" (извините за каламбур), поэтому я немного покопался в стандартной библиотеке c ++ и немного погуглил, и я вижу, что эти макросы __glibcpp_function_requires были изменены на __glibcxx_function_requires. Так что это исправило мою ошибку компилятора; однако, поскольку это для меня ново, мне интересно, что этот код делает для меня, и у меня возникают проблемы с поиском какой-либо документации или дешифрованием кода в библиотеке.

Я предполагаю, что смысл этих макросов в том, что когда компилятор расширяет шаблонную функцию, они будут выполнять некоторую проверку типов во время компиляции, чтобы увидеть, совместим ли используемый контейнер с этим алгоритмом. Другими словами, я предполагаю, что первый вызов проверяет, что _InputIter1 соответствует _InputIteratorConcept. Я просто в замешательстве или я на правильном пути? Кроме того, почему имена этих макросов были изменены в стандартной библиотеке c ++?

Ответы [ 4 ]

3 голосов
/ 28 октября 2009

«Концепции» были предложенной функцией для следующей версии C++, но они (относительно) недавно были отклонены вне стандарта, поэтому некоторое время не будут появляться для цитаты.

Они были разработаны для обеспечения ранней проверки требований к параметрам шаблона и, среди прочего, позволили бы гораздо более краткие сообщения об ошибках, когда для создания шаблона использовался тип, который не удовлетворял требуемым ограничениям.

2nd Edit: (см. Комментарии от dribeas и Jerry Coffin) Эти макросы g ++ являются внутренним механизмом проверки концепции и не имеют прямого отношения к предложенной новой функции языка с тем же именем. Поскольку они являются внутренними для g ++, вы можете (и, возможно, должны) безопасно удалить их без потери функциональности в шаблоне функций.

1 голос
/ 28 октября 2009

Существует два понятия (каламбур). Стандарт в том виде, в котором он определен, содержал предложение о концепциях в качестве стандартной языковой функции, которая помогла бы в компиляции и ... есть довольно много литературы о концепциях C ++ 0x, обсуждениях ...

Другая концепция - это та, которую вы только что достигли. STL, развернутый с реализациями g ++, имеет специальные проверки разработчика, которые также должны помочь в обнаружении ошибок. Они отличаются от предыдущих концепций тем, что они не являются языковой функцией и не предназначены для использования программистами, а скорее используются внутри библиотеки. Поскольку имена зарезервированы (они начинаются с двойного подчеркивания), разработчик компилятора / библиотеки может добавлять туда что угодно, если поведение библиотеки не отличается от того, что определяет стандарт.

Возвращаясь к тому, что вы делаете: код, который вы пытаетесь перенести на новый компилятор, является модифицированной версией std::set_intersect, как определено в стандартном [lib.set.intersection], чтобы возвращать только то, пересекаются ли они. без разбора всего двух диапазонов. Я бы либо использовал стандартную версию и проверил, что выходной итератор не был изменен, либо, если это проблема с производительностью, реализую его без проверок концепции, в зависимости от нестандартных скрытых символов, определенных компилятором, и возникает проблема с обслуживанием при обновлении компилятора. , Но это вы уже знаете.

1 голос
/ 28 октября 2009

Вы правы, первый вызов проверяет, что _InputIter1 реализует "входной итератор" концепция .

Эти макросы являются внутренними деталями реализации GLIBC (начиная с подчеркивания или двойного подчеркивания), поэтому разработчики GLIBC могут изменять их по своему желанию. Они не должны использоваться кодом пользователя.

Поскольку «концепции» больше не являются частью черновика C ++ 0x, для переносимой проверки концепций следует использовать стороннюю библиотеку, например Boost Concept Check Library .

0 голосов
/ 28 октября 2009

Как уже указывал Чарльз, прямая поддержка концепций в составе C ++ 0x была удалена из языка относительно недавно, и они почти наверняка не будут пересмотрены до следующего раунда стандартизации. Надеемся, что к тому времени будет больше согласия относительно того, что они должны быть на самом деле.

Однако значительное количество библиотек пытаются предоставить аналогичные возможности. Boost Concept Check Library , пожалуй, самая очевидная, и я полагаю, что большинство других основано на ней, по крайней мере, в концепции (если вы простите за каламбур). Относительно того, почему ребята из g ++ решили перейти с '* cxx' на '* cpp', я даже не могу догадаться - кроме того, что им кажется, что нарушение обратной совместимости как можно чаще - это хорошо (хотя на самом деле они предназначены только для внутреннего использования, поэтому изменение имени не должно сильно нарушать , а только их собственный код).

Это также довольно похоже на основную идею того, что Андрей Александреску представил в §2.1 Modern C ++ Design . Если вам нужна какая-то идея о том, как написать собственную концептуальную проверку, вы можете прочитать об этом (а также §2.7, где он применяет аналогичные методы для тестирования на конвертируемость и наследование). Несмотря на то, что проверяемые концепции различны, они хорошо объясняют большинство основных приемов, поэтому:

  1. У вас есть хороший шанс прочитать и понять шаблоны проверки концепций
  2. Если вы когда-либо решите написать что-то свое, у вас есть отправная точка

Редактировать: Вероятно, стоит отметить, что стандартные библиотеки для большинства современных компиляторов C ++ включают, по крайней мере, какие-то шаблоны проверки концепций. Очевидно, гну делает. Как и Комо. На самом деле, единственное, о чем я могу подумать, это, похоже, больше не включает в себя такие вещи, как MS VC ++ (который использует библиотеку Dinkumware). Вместо этого они сконцентрировались в основном на некоторой (довольно дорогой) отладке во время выполнения. Это также несколько полезно, но в совершенно другом направлении, и эти два не являются взаимоисключающими вообще.

...