Преобразовать итератор в указатель? - PullRequest
43 голосов
/ 13 апреля 2009

У меня есть std::vector с n элементами. Теперь мне нужно передать указатель на вектор с последними n-1 элементами в функцию.

Например, мой vector<int> foo содержит (5,2,6,87,251). Функция принимает vector<int>*, и я хочу передать ей указатель на (2,6,87,251).

Могу ли я просто (безопасно) взять итератор ++foo.begin(), преобразовать его в указатель и передать его функции? Или используйте &foo[1]?

ОБНОВЛЕНИЕ: Люди предлагают мне изменить мою функцию, чтобы взять итератор, а не указатель. Это кажется невозможным в моей ситуации, так как я упомянул функцию find из unordered_set<std::vector*>. Таким образом, в этом случае копирует n-1 элементы из foo в новый вектор и вызывает find с указателем на этот единственный вариант? Очень неэффективно! Это похоже на художника Шлемеля, тем более что мне нужно запросить множество подмножеств: последние элементы n-1, затем n-2 и т. Д. И посмотреть, есть ли они в unordered_set.

Ответы [ 12 ]

0 голосов
/ 14 апреля 2009

Я не проверял это, но не могли бы вы вместо этого использовать набор пар итераторов? Каждая пара итераторов будет представлять начальный и конечный итератор вектора последовательности. E.g.:

typedef std::vector<int> Seq;
typedef std::pair<Seq::const_iterator, Seq::const_iterator> SeqRange;

bool operator< (const SeqRange& lhs, const SeqRange& rhs)
{
    Seq::const_iterator lhsNext = lhs.first;
    Seq::const_iterator rhsNext = rhs.first;

    while (lhsNext != lhs.second && rhsNext != rhs.second)
        if (*lhsNext < *rhsNext)
            return true;
        else if (*lhsNext > *rhsNext)
            return false;

    return false;
}

typedef std::set<SeqRange, std::less<SeqRange> > SeqSet;

Seq sequences;

void test (const SeqSet& seqSet, const SeqRange& seq)
{
    bool find = seqSet.find (seq) != seqSet.end ();
    bool find2 = seqSet.find (SeqRange (seq.first + 1, seq.second)) != seqSet.end ();
}

Очевидно, что векторы должны храниться в другом месте, как и раньше. Также, если вектор последовательности изменяется, его запись в наборе должна быть удалена и добавлена ​​заново, поскольку итераторы могли измениться.

Jon

0 голосов
/ 13 апреля 2009

Если ваша функция действительно принимает vector<int> * (указатель на вектор), то вы должны передать &foo, так как это будет указатель на вектор. Очевидно, что это не просто решит вашу проблему, но вы не сможете напрямую преобразовать итератор в вектор, поскольку память по адресу итератора не будет напрямую обращаться к действительному вектору.

Вы можете создать новый вектор, вызвав векторный конструктор :

template <class InputIterator> vector(InputIterator, InputIterator)

Это создает новый вектор путем копирования элементов между двумя итераторами. Вы бы использовали это примерно так:

bar(std::vector<int>(foo.begin()+1, foo.end());
...