Iterator concepts | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Iterator primitives | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Algorithm concepts and utilities | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Indirect callable concepts | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Common algorithm requirements | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Utilities | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Iterator adaptors | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
Defined in header <iterator> | ||
template<class InputIt> typenamestd::iterator_traits<InputIt>::difference_type | (constexpr since C++17) | |
Returns the number of hops fromfirst tolast.
IfInputIt
is notLegacyRandomAccessIterator, the behavior is undefined iflast is notreachable fromfirst.
IfInputIt
isLegacyRandomAccessIterator, the behavior is undefined iffirst andlast are neither reachable from each other.
Contents |
first | - | iterator pointing to the first element |
last | - | iterator pointing to the end of the range |
Type requirements | ||
-InputIt must meet the requirements ofLegacyInputIterator. The operation is more efficient ifInputIt additionally meets the requirements ofLegacyRandomAccessIterator. |
The number of increments needed to go fromfirst tolast.
The value may be negative if random-access iterators are used andfirst is reachable fromlast. | (since C++11) |
Linear.
However, ifInputIt
additionally meets the requirements ofLegacyRandomAccessIterator, complexity is constant.
See also the implementations inlibstdc++ andlibc++.
C++98 implementation via tag dispatch, withconstexpr removed |
---|
namespace detail{template<class It>constexpr// required since C++17typenamestd::iterator_traits<It>::difference_type do_distance(It first, It last,std::input_iterator_tag){typenamestd::iterator_traits<It>::difference_type result=0;while(first!= last){++first;++result;}return result;} template<class It>constexpr// required since C++17typenamestd::iterator_traits<It>::difference_type do_distance(It first, It last,std::random_access_iterator_tag){return last- first;}}// namespace detail template<class It>constexpr// since C++17typenamestd::iterator_traits<It>::difference_type distance(It first, It last){return detail::do_distance(first, last,typenamestd::iterator_traits<It>::iterator_category());} |
C++17 implementation viaifconstexpr |
template<class It>constexprtypenamestd::iterator_traits<It>::difference_type distance(It first, It last){using category=typenamestd::iterator_traits<It>::iterator_category; static_assert(std::is_base_of_v<std::input_iterator_tag, category>); ifconstexpr(std::is_base_of_v<std::random_access_iterator_tag, category>)return last- first;else{typenamestd::iterator_traits<It>::difference_type result=0;while(first!= last){++first;++result;}return result;}} |
#include <iostream>#include <iterator>#include <vector> int main(){std::vector<int> v{3,1,4};std::cout<<"distance(first, last) = "<< std::distance(v.begin(), v.end())<<'\n'<<"distance(last, first) = "<< std::distance(v.end(), v.begin())<<'\n';// the behavior is undefined (until LWG940) staticconstexprauto il={3,1,4};// Since C++17 `distance` can be used in constexpr context. static_assert(std::distance(il.begin(), il.end())==3); static_assert(std::distance(il.end(), il.begin())==-3);}
Output:
distance(first, last) = 3distance(last, first) = -3
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
LWG 940 | C++98 | the wording was unclear for the case wherefirst is reachable fromlast | made clear |
advances an iterator by given distance (function template)[edit] | |
returns the number of elements satisfying specific criteria (function template)[edit] | |
(C++20) | returns the distance between an iterator and a sentinel, or between the beginning and end of a range (algorithm function object)[edit] |