Пользовательский класс итератор, следующий за списком целочисленных индексов? - PullRequest
0 голосов
/ 30 октября 2018

У меня есть шаблонный класс myClass, которому принадлежит экземпляр std::vector, и я перегрузил оператор [], чтобы взять в качестве аргумента std::vector<int> индексов для вектора-члена и вернуть вторичный класс mySubset

template <typename _type> 
class myClass {
    // ...
    std::vector<_type> data;
    // ...
    class mySubset {
        myClass<_type>* mc; 
        const std::vector<int>::iterator &idx; 
    public:
        //constructor
        mySubset(myClass<_type> * _m, const std::vector<int>& _idx);
        // input operator overloads (for data and range input)
        template <typename _input_type> mySubset& operator=(const std::vector<_input_type>& _vals);
        mySubset& operator=(const mySubset& _sbst);
    };

public:

    myClass();
    ~myClass(); 
    // ...
    //acess operator
    mySubset operator[](const std::vector<int>& _idx) { return mySubset(_idx); };
    // ...
    //iterator
    typename std::vector<_type>::iterator begin() {return data.begin();};
    typename std::vector<_type>::iterator end();  {return data.end();  };
    // ...
}

Я могу получать и устанавливать значения напрямую с помощью оператора [], но я бы хотел использовать циклы на основе диапазона, например,

// ...
myClass<float> foo;
// ...
std::vector<int> indices (3);
indices[0] = 3;
indices[1] = 6;
indices[2] = 10;
// ...
foo[indices] = std::vector<float> (3, 0.47);

for (auto& fval : foo[indices]) { /* do stuff*/}

Из того, что я собрал, мне понадобится advance( InputIt& it, Distance n ); для достижения того, что я хочу, и добавление begin() и end() членов к mySubset, которые возвращают объект типа итератора с ++ оператор, увеличивающий итератор путем просмотра вектора индекса:

class myIterator {
    mySubset * sb;
    std::vector<_type> it; // myClass::data iterator
public:
    myIterator(mySubset * _sb, int pos): sb(_sb) { it = sb->mc->data.begin() + sb->idx[0]; }   ;
    myIterator& operator++() { };
    myIterator& operator!=(myIterator& _other) { };
};

//.. mySubset
myIterator begin();
myIterator end();

Но в настоящий момент у меня возникают проблемы с пониманием того, какой именно синтаксис необходим для достижения этой цели?

1 Ответ

0 голосов
/ 30 октября 2018

Я буду ленивым.

Иди и реализуй _type& operator[](size_t) и .size() на mySubset.

template<class C>
struct range_for_helper{
  using self=range_for_helper;
  C* c=0;
  std::size_t i = 0;
  self(C* cin, std::size_t idx):c(cin),i(idx){}
  friend bool operator==(self lhs, self rhs){return lhs.i==rhs.i;}
  friend bool operator!=(self lhs, self rhs){return lhs.i!=rhs.i;}
  void operator++(){++i;}
  decltype(auto) operator*(){ return (*c)[i]; }
};

Затем добавьте

до mySubset и готово.

Это не настоящий итератор, но достаточно для циклов for(:). Его можно расширить до реального итератора, как я уже сказал, ленивый.

Также:

range_for_helper<mySubset> begin() const { return {this,0}; }
range_for_helper<mySubset> end() const { return {this,size()}; }

просто работает, если ваш [] перегружен на const, так что это хорошо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...