Как работают макросы __glibcxx_function_requires и __glibcxx_requires_valid_range?

template<typename _InputIterator, typename _Tp, typename _BinaryOperation>
inline _Tp
accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOperation __binary_op)
{
    // concept requirements
    __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
    __glibcxx_requires_valid_range(__first, __last);

    for (; __first != __last; ++__first)
        __init = __binary_op(__init, *__first);
    return __init;
}

Я посмотрел на определение функции накопления в библиотеке stl. Здесь я нашел два макроса __glibcxx_function_requires и __glibcxx_requires_valid_range, которые определены следующим образом:

#define __glibcxx_function_requires(...)
# define __glibcxx_requires_valid_range(_First,_Last)

Подскажите пожалуйста, как они работают и чем занимаются?

1 ответ

Решение

Когда _GLIBCXX_CONCEPT_CHECKS определяется, так и это.

#define __glibcxx_function_requires(...)                                 \
         __gnu_cxx::__function_requires< __gnu_cxx::__VA_ARGS__ >();

Итак, ваш опубликованный код:

__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)

Разрешается к этому:

__gnu_cxx::__function_requires< _InputIteratorConcept<_InputIterator> >();

Который указывает на:

void (_InputIteratorConcept<_InputIterator>::*__x)() _IsUnused = &_InputIteratorConcept<_InputIterator>::__constraints;

Это заставляет экземпляр _InputIteratorConcept<_InputIterator>::__constraints, который использует typedefS, чтобы сломать компиляцию, когда _InputIterator не похож на итератор.

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

Другие вопросы по тегам