Преобразовать итератор в указатель?

Избегайте цикла и выполните один INSERT INTO ... SELECT запрос. Прямо сейчас вы повторно используете один и тот же курсор снаружи и внутри цикла, вызывая проблемы с обработкой. Либо используйте два разных курсора, либо эффективно объединяйте и выполняйте запрос действия запуска механизма базы данных:

sql = '''INSERT INTO Counts (org, [count])
         SELECT SUBSTR(email, INSTR(email, '@')+1) AS org, 
                SUM(count) as [count]
         FROM Em 
         GROUP BY org 
         ORDER BY count DESC
      '''

cur.execute(sql)
conn.commit()
44
задан lsalamon 13 April 2009 в 12:56
поделиться

9 ответов

Это кажется невозможным в моей ситуации, поскольку упомянутая мною функция является функцией поиска unordered_set .

Используете ли вы пользовательские объекты хеш-функции / предиката? Если нет, то вы должны передать unordered_set *> :: find () указатель на точный вектор, который вы хотите найти. Указатель на другой вектор с таким же содержимым не будет работать. Это не очень полезно для поиска, если не сказать больше.

Было бы лучше использовать unordered_set > , потому что тогда вы можете выполнять поиск по значению. Я думаю, что это также потребует пользовательского объекта хэш-функции, потому что хэш , насколько мне известно, не имеет специализации для vector .

В любом случае, указатель на середину вектор сам по себе не является вектором, как объяснили другие. Вы не можете конвертировать итератор в указатель на вектор без копирования его содержимого.

8
ответ дан bk1e 26 November 2019 в 21:50
поделиться

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

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 ();
}

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

Джон

0
ответ дан jon-hanson 26 November 2019 в 21:50
поделиться

Прямой ответ на ваш вопрос - да. Если foo является вектором, вы можете сделать это: & foo [1].

Однако это работает только для векторов, потому что в стандарте говорится, что векторы реализуют хранилище с использованием неконтролируемой памяти.

Но вы все еще можете (и, вероятно, должны ) передайте итераторы вместо необработанных указателей, потому что это более выразительно. Проходящие итераторы не делают копию вектора.

2
ответ дан John Dibling 26 November 2019 в 21:50
поделиться

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

Указатель на vector не является вообще то же самое, что указатель на элементы вектора.

Для этого вам нужно создать новый вектор , содержащий только те элементы, на которые вы хотите передать указатель. Примерно так:

 vector<int> tempVector( foo.begin()+1, foo.end());

 // now you can pass &tempVector to your function

Однако, если ваша функция получает указатель на массив из int, вы можете передать & foo [1] .

1
ответ дан Michael Burr 26 November 2019 в 21:50
поделиться

Ваша функция не должна принимать vector * ; в зависимости от ситуации следует использовать vector :: iterator или vector :: const_iterator . Затем просто введите foo.begin () + 1 .

3
ответ дан Chris Jester-Young 26 November 2019 в 21:50
поделиться

Если можешь, лучшим выбором может быть изменение функции на использование итератора для элемента или нового вектора (если он не изменяется).

Хотя вы можете делать такие вещи с массивами, так как знаете, как они хранятся Это, вероятно, плохая идея сделать то же самое с векторами. & foo [1] не имеет тип vector * .

Кроме того, хотя реализация STL доступна онлайн, обычно рискованно пытаться полагаться на внутренний структура абстракции.

6
ответ дан Uri 26 November 2019 в 21:50
поделиться

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

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

template <class InputIterator> vector(InputIterator, InputIterator)

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

bar(std::vector<int>(foo.begin()+1, foo.end());
0
ответ дан 1800 INFORMATION 26 November 2019 в 21:50
поделиться

Вектор - это контейнер с полным владением своими элементами. Один вектор не может содержать частичное представление другого, даже const-представление. Это коренная причина здесь.

Если вам это нужно, создайте свой собственный контейнер, который имеет представления со слабым_пломером к данным, или посмотрите на диапазоны. Пара итераторов (даже указатели работают как итераторы в векторе) или, что еще лучше, boost :: iterator_range, которые работают довольно легко.

Это зависит от шаблонности вашего кода. Используйте std :: pair, если вам нужно скрыть код в cpp.

3
ответ дан 26 November 2019 в 21:50
поделиться

Здесь оно есть, получение ссылки на соответствующее указатель итератора Использование:

Пример:

string my_str= "hello world";

string::iterator it(my_str.begin());

char* pointer_inside_buffer=&(*it); //<--

[Оператор уведомления * возвращает ссылку , чтобы делать и на ссылке даст вам адрес].

87
ответ дан 26 November 2019 в 21:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: