I am having trouble using view_facade (from range-v3) to create a view that provides both const and non-const access. As an example, I tried modifying the view_facade test (in test/view_facade.cpp) to allow non-const access (by default it only allows const access):
struct MyRange
: ranges::range_facade<MyRange>
{
private:
friend struct ranges::range_access;
std::vector<int> ints_;
template <bool isConst>
struct cursor
{
private:
using It = typename std::conditional<isConst, std::vector<int>::const_iterator, std::vector<int>::iterator>::type;
using RefType = typename std::conditional<isConst, int const&, int&>::type;
It iter;
public:
cursor() = default;
cursor(It it)
: iter(it)
{}
RefType current() const
{
return *iter;
}
//...
};
/* // Uncommenting these overloads will cause an error, below.
cursor<true> begin_cursor() const
{
return {ints_.begin()};
}
cursor<true> end_cursor() const
{
return {ints_.end()};
}
*/
cursor<false> begin_cursor()
{
return {ints_.begin()};
}
cursor<false> end_cursor()
{
return {ints_.end()};
}
public:
MyRange()
: ints_{1, 2, 3, 4, 5, 6, 7}
{}
};
int main() {
MyRange nc;
int& nci = *nc.begin(); // error here when const overloads present.
}
Full code here.
This works fine with the const overloads of begin_cursor and end_cursor commented out. However, if I add those overloads back in, the following error is generated on the indicated line (GCC 5.1):
error: binding 'const int' to reference of type 'int&' discards qualifiers
It seems to be selecting the const version, giving me a const iterator. What I want is: const iterators for const objects, and non-const iterators for non-const objects. How can I achieve that?