У меня проблемы с использованием view_facade (из Диапазон-v3) для создания представления, которое обеспечивает как постоянный, так и неконстантный доступ. В качестве примера я попытался изменить тест view_facade (в test / view_facade.cpp), чтобы разрешить неконстантный доступ (по умолчанию он разрешает только константный доступ):
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.
}
Это прекрасно работает с константными перегрузками begin_cursor и end_cursor, закомментированных. Однако, если я добавлю эти перегрузки обратно, в указанной строке будет сгенерирована следующая ошибка (GCC 5.1):
error: binding 'const int' to reference of type 'int&' discards qualifiers
Кажется, он выбирает const-версию, давая мне const-итератор. Я хочу: константные итераторы для константных объектов и неконстантные итераторы для неконстантных объектов. Как я могу этого достичь?
view_facade
для строительства просмотров. Представления относятся к данным, которые им не принадлежат. Они как указатели в том, что логически они — косвенные указания. И, как указатели, на высшем уровне const
должен не влияет на const
-ность данных, на которые ссылаются. То ли ты разыграешь int*
или int*const
результат тот же: int&
,
Ваше мнение не является представлением. Он владеет своими данными. (См. vector<int> ints_
член данных.) Пытаюсь использовать view_facade
превратить эту структуру данных в представление неизбежно приведет к разочарованию. Это очень много задумано. Представления отличаются от контейнеров. Извините, библиотека Range-v3 не имеет фасада контейнера.
(Что происходит: так как представления представляют косвенность, view_facade
очень старается сделать константный и неконстантный begin()
а также end()
вернуть те же типы. Если cursor_begin() const
присутствует, что один всегда выбран. Всегда. Когда это нарушает код, это обычно происходит потому, что этот код путает контейнеры с представлениями.)