10
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ライブラリのaccumulate関数の定義を見ました。ここで、次のように定義されている 2 つのマクロ __glibcxx_function_requires と __glibcxx_requires_valid_range を見つけました。

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

それらがどのように機能し、何をしているのか、説明していただけますか?

4

1 に答える 1

13

_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;

これは のインスタンス化を強制し、がイテレータに似ていない場合に s_InputIteratorConcept<_InputIterator>::__constraintsを使用typedefしてコンパイルを中断します。_InputIterator

__glibcxx_requires_valid_range同様の手法を使用して、反復子の型に応じていくつかの関数のいずれかを呼び出します。適切な場合 (そして十分に速い場合)、それ__lastは後に続くことをアサートします__first

于 2013-04-10T21:00:05.013 に答える