проверить, к какому вектору принадлежит итератор - PullRequest
0 голосов
/ 11 июня 2018

У меня есть 3 итератора, которые принадлежат 3 векторам A, B и C. Для этих 3 итераторов вызывается функция minn, которая возвращает итератор с минимальным значением.Теперь, как я могу узнать, к какому вектору относится возвращаемый итератор minit?код -

vector<int>::iterator a = A.begin(), b = B.begin(), c = C.begin();
auto minit = minn(a,b,c);

Ответы [ 3 ]

0 голосов
/ 11 июня 2018

Самый простой вариант - не передавать эти итераторы по значению, поэтому при изменении minit меняется любой из a, b или c.

bool itLess(std::vector<int>::iterator& l, std::vector<int>::iterator& r)
{
    return *l < *r;
}

for (
    auto a = A.begin(), b = B.begin(), c = C.begin(); 
    a != A.end() && b != B.end() && c != C.end();
    )
{
    auto [minit, maxit] = std::minmax({std::ref(a), std::ref(b), std::ref(c)}, itLess);
    // use minit.get() and maxit.get()
}

Посмотреть на колиру

0 голосов
/ 11 июня 2018

Мы можем воспользоваться тем, что vector хранит свои элементы в одном непрерывном массиве.Мы можем проверить, находится ли элемент, указанный итератором, в памяти между началом и концом этого массива.

template<typename T>
bool isFromVector(const typename std::vector<T>::const_iterator &i, const std::vector<T> &v)
{
    const T *const dataBeginning = v.data();
    const T *const dataEnd = v.data() + v.size();
    const T *const element = &*i;
    return std::less_equal<const T*>()(dataBeginning, element) && std::greater<const T*>()(dataEnd, element);
}
0 голосов
/ 11 июня 2018

В вашем конкретном случае возвращение std::pair с итератором и целым числом, помечающим выбранный аргумент, может помочь.На самом деле вы можете вернуть только целое число, и тогда вызывающая сторона сможет использовать соответствующий итератор - это масштабирует его до вектора / массива итераторов.

Необходимость сделать это может быть немногоплохой дизайн.Если вам нужно что-то сделать с этим конкретным итератором, просто верните сам итератор по ссылке и сделайте это:

vector<int>::iterator& minn(vector<int>::iterator& A, vector<int>::iterator& B, vector<int>::iterator& C) {
    ...
    //Assuming you found the minimal position in each iterator, just return the correct reference
    if (*A < *B)
        if (*A < *C) return A;
    if (*B < *C) return B;
    return C;

//inside caller
...
vector<int>::iterator& minit = vector<int>::iterator(A,B,C);
minit++;

сработает, без явного написания в коде вектора, над которым вы работаете....

(например, ++minit) без явного написания в вашем коде итератора этого.На самом деле, вы можете захотеть сделать это внутри minn.

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