简体   繁体   中英

What does it take to be an `stl` algorithm compatible container?

1) For a given stl algorithm, how does one find out what custom container/iterator features one needs to implement in order to use said container?

2) What needs to be implemented to make container fully compatible with all stl algorithms?

In C++11 standard it is stated in §25.1, in the footnotes:

3 All of the algorithms are separated from the particular implementations of data structures and are parameterized by iterator types. Because of this, they can work with program-defined data structures, as long as these data structures have iterator types satisfying the assumptions on the algorithms.

and then:

5 Throughout this Clause, the names of template parameters are used to express type requirements. If an algorithm's template parameter is InputIterator, InputIterator1, or InputIterator2, the actual template argument shall satisfy the requirements of an input iterator (24.2.3). If an algorithm's template parameter is OutputIterator, OutputIterator1, or OutputIterator2, the actual template argument shall satisfy the requirements of an output iterator (§24.2.4). If an algorithm's template parameter is ForwardIterator, ForwardIterator1, or ForwardIterator2, the actual template argument shall satisfy the requirements of a forward iterator (§24.2.5). If an algorithm's template parameter is BidirectionalIterator, Bidirectional-Iterator1, or BidirectionalIterator2, the actual template argument shall satisfy the requirements of a bidirectional iterator (§24.2.6). If an algorithm's template parameter is RandomAccessIterator, Random- AccessIterator1, or RandomAccessIterator2, the actual template argument shall satisfy the requirements of a random-access iterator (§24.2.7).

So basically you need to provide your custom class a way to retrieve the usual iterators and these object must satisfy the requirement depending on which algorithm you want to support.

For example, let's take std::any_of , you can see it's declared as

template <class InputIterator, class Predicate> 
bool any_of(InputIterator first, InputIterator last, Predicate pred);

So you need to provide it an input iterator, then you can see at §24.2.3 the requirement for it and implement them:

  • contextually convertible to bool ( a != b )
  • convertible to T ( *a )
  • dereferenceable ( a->m )
  • incrementable

Same story for each kind of iterator.

STL algorithms use template types to describe the requirements of the function. If you take std::sort as an example

template<class RandomAccessIterator>
void sort(RandomAccessIterator first, RandomAccessIterator last);

We can see that wee need to pass a random access compliant iterator. So as long as the container you have has an iterator type of RandomAccessIterator or it supports all of the operations that RandomAccessIterator supports then you can use it with std::sort .

If we look at the iterator hierarchy on cppreference We can see that in the current standard a RandomAccessIterator is a super-set of all other iterator types and supports all of the operations that the other iterators support. So if a function calls for a InputIterator we can still give it an RandomAccessIterator.

So right now if your container has a RandomAccessIterator you can use it in any of the STL algorithms.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM