Установите iterator_bracket_proxy для boost :: iterator_adapter - PullRequest
0 голосов
/ 09 мая 2018

Я пытаюсь сделать итератор произвольного доступа It.

Операция индексирования It должна вернуть Node.

Но это не так. Как это сделать?

Тест:

#include <iostream>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/iterator/counting_iterator.hpp>

template<typename T>
class Node {
public:
    explicit Node(const T index) : index_(index) {}
    const T index_;
};

template<typename T>
class It
        : public boost::iterator_adaptor<
                It<T>, // Derived
                boost::counting_iterator<T>, // Base
                Node<T>, // Value
                std::random_access_iterator_tag, // CategoryOrTraversal
                Node<T>, // Reference
                boost::use_default  // Difference
        > {
protected:
    using self_type = It<T>;
    using node_type = Node<T>;
public:
    explicit It(const T& x) : self_type::iterator_adaptor_(x){}

    Node<T> operator*() const {
        // Dereferencing gives a index instead of a reference.
        auto& base_iterator = this->base_reference();
        return Node<T>(*base_iterator);
    }
protected:
    friend class boost::iterator_core_access;
};

int main() {
    It<int> a(10);
    std::cout << (*a).index_ << "\n";
    // a[4] is a
    // class boost::iterators::detail
    //     ::operator_brackets_proxy<It<int> >
    // instead of a Node<int>.
    std::cout << a[4].index_ << "\n";
}

Ошибка:

error: ‘boost::iterators::detail
    ::operator_brackets_result<It<int>, Node<int>, Node<int> >::type 
{aka class boost::iterators::detail
    ::operator_brackets_proxy<It<int> >}’ 
has no member named ‘index_’
     std::cout << a[4].index_ << "\n";
                       ^~~~~~

1 Ответ

0 голосов
/ 09 мая 2018

См. Документацию operator[]

Записываемые итераторы, созданные с использованием iterator_facade, реализуют семантику, требуемую предпочтительным разрешением для выпуска 299 и принятую по предложению n1550 :
(1) результат p[n] является объектом, конвертируемым в value_type итератора, а p[n] = x эквивалентен *(p + n) = x (Примечание: этот объект результата может быть реализован как прокси, содержащий копию p+n). Этот подход будет работать правильно для любого итератора с произвольным доступом независимо от других деталей его реализации.
(2) Пользователь, который знает больше о реализации своего итератора, может свободно реализовать operator[], который возвращает lvalue в производном классе итератора; он будет скрывать тот, что предоставляется iterator_facade от клиентов ее итератора.

Начиная с (1) , вы можете написать:

std::cout << static_cast<Node<int>>(a[4]).index_ << "\n";

или (2) агрегат operator[]:

Node<T> operator[](std::ptrdiff_t n) const {
    return *std::next(*this,n);
}
std::cout << a[4].index_ << "\n";

или напишите вместо:

std::cout << std::next(a,4)->index_ << "\n";
std::cout << (a+4)->index_ << "\n";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...