Contiguous iterator detection

亡梦爱人 提交于 2019-11-26 23:00:43

问题


C++17 introduced the concept of ContiguousIterator http://en.cppreference.com/w/cpp/iterator. However it doesn't seem that there are plans to have a contiguous_iterator_tag (in the same way we now have random_access_iterator_tag) reported by std::iterator_traits<It>::iterator_category.

Why is contiguous_iterator_tag missing?

Is there a conventional protocol to determine if an iterator is Contiguous? Or a compile time test?

In the past I mentioned that for containers if there is a .data() member that converts to a pointer to ::value type and there is .size() member convertible to pointer differences, then one should assume that the container is contiguous, but I can't pull an analogous feature of iterators.

One solution could be to have also a data function for contiguous iterators.

Of course the Contiguous concept works if &(it[n]) == (&(*it)) + n, for all n, but this can't be checked at compile time.


EDIT: I found this video which puts this in the more broader context of C++ concepts. CppCon 2016: "Building and Extending the Iterator Hierarchy in a Modern, Multicore World" by Patrick Niedzielski. The solution uses concepts (Lite) but at the end the idea is that contiguous iterators should implement a pointer_from function (same as my data(...) function).

The conclusion is that concepts will help formalizing the theory, but they are not magic, in the sense that someone, somewhere will define new especially named functions over iterators that are contiguous. The talk generalizes to segmented iterators (with corresponding functions segment and local), unfortunatelly it doesn't say anything about strided pointers.


回答1:


The rationale is given in N4284, which is the adopted version of the contiguous iterators proposal:

This paper introduces the term "contiguous iterator" as a refinement of random-access iterator, without introducing a corresponding contiguous_iterator_tag, which was found to break code during the Issaquah discussions of Nevin Liber's paper N3884 "Contiguous Iterators: A Refinement of Random Access Iterators".

Some code was broken because it assumed that std::random_access_iterator couldn't be refined, and had explicit checks against it. Basically it broke bad code that didn't rely on polymorphism to check for the categories of iterators, but it broke code nonetheless, so contiguous_iterator_tag was removed from the proposal.

Also, there was an additional problem with std::reverse_iterator-like classes: a reversed contiguous iterator can't be a contiguous iterator, but a regular random-access iterator. This problem could have been solved for std::reverse_iterator, but more user-defined iterator wrappers that augment an iterator while copying its iterator category would have either lied or stopped working correctly (for example Boost iterator adaptors).


SInce my original answer above, std::contiguous_iterator_tag was brought back in the Ranges TS and will be present in C++20. It avoids the issues mentioned above by not providing it through std::iterator_traits<T>::iterator_category but through std::iterator_traits<T>::iterator_concept so as to ne break any existing code.

The concepts ContiguousIterator and ContiguousRange. Those currently mainly differ from their RandomAccess counterpart in that they check the iterator_concept to known whether it's a random-access or a contiguous iterator. However, another proposal, Helpful pointers for ContiguousIterator also proposes that contiguous iterators implement a to_address function which returns the underlying pointer. I don't know whether this proposal is on track to get accepted or not.



来源:https://stackoverflow.com/questions/42851957/contiguous-iterator-detection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!