スルーiterator_traits
・タグ発送:
template<class InputIterator, class Distance>
void advance_impl(InputIterator& i, Distance n, std::random_access_iterator_tag) {
i += n;
}
template<class InputIterator, class Distance>
void advance_impl(InputIterator& i, Distance n, std::bidirectional_iterator_tag) {
if (n < 0) {
while (n++) --i;
} else {
while (n--) ++i;
}
}
template<class InputIterator, class Distance>
void advance_impl(InputIterator& i, Distance n, std::input_iterator_tag) {
assert(n >= 0);
while (n--) ++i;
}
template<class InputIterator, class Distance>
void advance (InputIterator& i, Distance n) {
advance_impl(i, n,
typename std::iterator_traits<InputIterator>::iterator_category());
}
iterator_category
は型 (std::input_iterator_tag
などの 1 つ) であるためiterator_category()
、関数呼び出しではないことに注意してください。その型の一時的な prvalueを構築する式です。の適切なオーバーロードadvance_impl
は、通常のオーバーロード解決によって選択されます。これをタグディスパッチと呼びます。同様に、次のように書くこともできます:
template<class InputIterator, class Distance>
void advance (InputIterator& i, Distance n) {
typename std::iterator_traits<InputIterator>::iterator_category the_tag;
advance_impl(i, n, the_tag);
}
のオーバーロードはadvance_impl
、選択したタグ タイプのインスタンスである名前のない引数を 3 番目の引数として受け取ります。