For C++17, it has a small change with proposal p0184r0,which make it possible to specify different begin() and end() type for a user-defined type, to compatible with range-based for. But it seems gcc will failure on following cases:
#include<iterator>
#include<iostream>
using namespace std;
class read_t
{
public:
using data_type = int;
read_t()
{
}
~read_t()
{
}
struct end_marker {};
class iterator
{
public:
using iterator_category = std::input_iterator_tag;
using value_type = data_type;
using difference_type = long int;
iterator(read_t& reader)
: m_reader(reader)
{}
data_type operator*()
{
return m_i;
}
iterator& operator++()
{
return *this;
}
bool operator!=(end_marker&)
{
m_i ++;
return m_i <= 3;
}
private:
read_t& m_reader;
int m_i = 0;
};
iterator begin() { return iterator(*this); }
end_marker end() { return end_marker{}; }
};
int main()
{
using namespace std;
for (auto i : read_t())
{
cout << i << endl;
}
}
with error message as:
~/test >>> g++ -std=c++17 -o b0 b.cpp
b.cpp: In function ‘int main()’:
b.cpp:56:26: error: inconsistent begin/end types in range-based ‘for’ statement: ‘read_t::iterator’ and ‘read_t::end_marker’
56 | for (auto i : read_t())
| ^
~/test >>>
My gcc compiler is gcc 10.2.0, on Manjaro platform. The same code is passed with clang 11.0.1 and vs 2019.