As I understand it, before C++20 iterators were just a concept defined by the standard. Now in C++20 they are real language concepts which are checked at compile time. I'm wondering if I'm safe to assume that I can consume a C++20 iterator in my API and pass it to any pre-C++20 API without it breaking:
Demo
#include <string>
#include <concepts>
#include <cstdio>
#include <utility>
auto write_string(std::input_iterator auto it) -> void { // <-- C++20 iterator
std::string ret = "Danger";
std::copy(ret.begin(), ret.end(), it); // <-- requires LegacyInputIterator
}
int main()
{
std::string str = "Austin is my middle name";
write_string(str.begin());
printf("%.*s\n", (int)str.size(), str.data());
}
std::copy requires that the type of the third parameter must meet the requirements of LegacyOutputIterator, that is, it must support the writing operation, which is not guaranteed by std::input_iterator.
In C++20, the corresponding concept is std::output_iterator, so you can redeclare write_string as
void write_string(std::output_iterator<const char&> auto it) {
std::string ret = "Danger";
std::copy(ret.begin(), ret.end(), it);
}
This guarantees that the type of it satisfies the syntax requirements for output iterators written to char.
(Although the C++20 iterator system is very different from C++98/C++17, the requirements for output iterators are basically equivalent. so in your example, using std::output_iterator to check the requirement of LegacyOutputIterator is fine)
No.
The old LegacyInputIterator concept also required std::equality_comparable, which is no longer required for std::input_iterator.
Therefore, a C++20 iterator type that's not std::equality_comparable is not a LegacyInputIterator and might break old API's.
std::output_iterator however is not required to be std::equality_comparable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With