Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
0 / 0 / 0
Регистрация: 27.03.2013
Сообщений: 15
1

Конфликт итераторов

06.10.2014, 23:19. Показов 994. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток. Пишу Timsort с использованием шаблонов и итераторов. Написал класс CTimsort, в нем все необходимые методы и их реализацию. Приведу небольшой кусок кода:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <vector>
#include <iterator>
 
template<typename RandomAccessIterator, typename CCompare> class CTimsort
{
    static const int MIN_RUN_SIZE = 32;
    static const int MIN_GALLOP = 7;
    static const int INITIAL_TMP_STORAGE_LENGTH = 256; //maximum initial size of tmp array, which is used for merging
    RandomAccessIterator minGallop = 7;
 
    struct Run
    {
        RandomAccessIterator runBase;
        typename std::iterator_traits<RandomAccessIterator>::difference_type runLength;
        Run();
        Run(RandomAccessIterator b, typename std::iterator_traits<RandomAccessIterator>::difference_type l) : runBase(b), runLength(l) {}
    };
 
    //a stack for runs to be merged
    std::vector<Run> runs;
 
    /*
     *returns the run on the runPosition
     *runPosition - the position of the run in the stack
     */
    Run* GetRun(RandomAccessIterator runPosition)
    {
        Run* r = &runs.at(runPosition);
        return r;
    }
 
.............
Возникает ошибка на этапе компиляции:
no matching function for call to 'std::vector<CTimsort<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, std::less<int> >::Run, std::allocator<CTimsort<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, std::less<int> >::Run> >::at(__gnu_cxx::__normal_iterator<int*, std::vector<int> >&)'
В остальных местах кода, где используется std::vector<int>::at(), та же самая штуковина вылазит. Что я делаю не так?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.10.2014, 23:19
Ответы с готовыми решениями:

Итерации итераторов С++
Задача &quot;каждому эл-ту вектора присвоить значение его индекса, скопировать это еще в другой вектор и...

Применение итераторов
Подскажите пожалуйста, в чем практичность итераторов, то бишь для чего нужны они в программах?

Использование итераторов
Добрый день, форум! Слышал что вместо того чтобы писать несколько перегрузок для функции,...

Перегрузка итераторов
Почему переполняется итератор vector&lt;char&gt;::iterator p = v.begin(); вот код : int _tmain (int...

7
18894 / 9851 / 2410
Регистрация: 30.01.2014
Сообщений: 17,295
06.10.2014, 23:21 2
Цитата Сообщение от maked0n Посмотреть сообщение
Что я делаю не так?
Метод at() у std::vector принимает индекс (size_t), а не итератор.
0
0 / 0 / 0
Регистрация: 27.03.2013
Сообщений: 15
06.10.2014, 23:28  [ТС] 3
А такой код будет правильно работать? Ведь runPosition, на сколько я понимаю, не будет "принадлежать" этому контейнеру.
C++
1
2
3
4
5
Run GetRun(RandomAccessIterator runPosition)
    {
        Run r = *(runPosition);
        return r;
    }
К тому же, тогда не работает такой код:
C++
1
*(runPosition).runLenght = 2;
0
18894 / 9851 / 2410
Регистрация: 30.01.2014
Сообщений: 17,295
06.10.2014, 23:39 4
Цитата Сообщение от maked0n Посмотреть сообщение
Ведь runPosition, на сколько я понимаю, не будет "принадлежать" этому контейнеру.
Нужно больше кода.
Если итератор получен у контейнера, он "принадлежит" ему так или иначе.

Цитата Сообщение от maked0n Посмотреть сообщение
К тому же, тогда не работает такой код:
Без контекста нельзя ни подтвердить ни опровергнуть это утверждение.

Добавлено через 1 минуту
PS. путаница с итераторами должна уйти, если начать воспринимать итератор как указатель на элемент.
0
0 / 0 / 0
Регистрация: 27.03.2013
Сообщений: 15
07.10.2014, 00:37  [ТС] 5
Вот весь "проблемный" код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <vector>
#include <iterator>
 
template<typename RandomAccessIterator, typename CCompare> class CTimsort
{
    static const int MIN_RUN_SIZE = 32;
    static const int MIN_GALLOP = 7;
    static const int INITIAL_TMP_STORAGE_LENGTH = 256; //maximum initial size of tmp array, which is used for merging
    RandomAccessIterator minGallop = 7;
 
    struct Run
    {
        RandomAccessIterator runBase;
        typename std::iterator_traits<RandomAccessIterator>::difference_type runLength;
        Run();
        Run(RandomAccessIterator b, typename std::iterator_traits<RandomAccessIterator>::difference_type l) : runBase(b), runLength(l) {}
    };
 
    std::vector<Run> runs;
 
    Run GetRun(RandomAccessIterator runPosition)
    {
        Run r = *(runPosition);
        return r;
    }
 
.....
 
void MergeCollapse(RandomAccessIterator firstElement, RandomAccessIterator lastElement, CCompare comp)
    {
        typename std::iterator_traits<RandomAccessIterator>::difference_type subtrahend = 1;
        while(runs.size() > 1)
        {
            if(std::distance(runs.end(), runs.begin()) > subtrahend &&
                    GetRun(runs.end() - subtrahend - 1).runLength <= GetRun(runs.end() - subtrahend).runLength +
                    GetRun(runs.end() - subtrahend + 1).runLength)
            {
                if(GetRun(runs.end() - subtrahend - 1).runLength < GetRun(runs.end() - subtrahend + 1).runLength)  --subtrahend;
                MergeAt(firstElement, lastElement, runs.end() - subtrahend, comp);
            }
            else if(GetRun(runs.end() - subtrahend).runLength <= GetRun(runs.end() - subtrahend + 1).runLength)
                MergeAt(firstElement, lastElement, runs.end() - subtrahend, comp);
            else break;
        }
    }
 
    void MergeForceCollapse(RandomAccessIterator firstElement, RandomAccessIterator lastElement, CCompare comp)
    {
        while(runs.size() > 1)
        {
            typename std::iterator_traits<RandomAccessIterator>::difference_type subtrahend = 1;
            if((runs.end() - subtrahend) > runs.begin() &&
                    GetRun(runs.end() - subtrahend - 1).runLength < GetRun(runs.end() - subtrahend + 1).runLength) --subtrahend;
            MergeAt(firstElement, lastElement, runs.end() - subtrahend, comp);
        }
    }
Я немного подправил код, ошибка поменялась:
no matching function for call to 'CTimsort<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, std::less<int> >::GetRun(__gnu_cxx::__normal_iterator<CTimsort<__gnu_cxx::__normal_iterator<int *, std::vector<int> >, std::less<int> >::Run*, std::vector<CTimsort<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, std::less<int> >::Run, std::allocator<CTimsort<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, std::less<int> >::Run> > >)'
Возникает при каждом использовании GetRun().

Также, в 23 строке следующая ошибка:
conversion from 'int' to non-scalar type 'CTimsort<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, std::less<int> >::Run' requested.
0
Эксперт по математике/физикеЭксперт С++
2048 / 1366 / 395
Регистрация: 16.05.2013
Сообщений: 3,506
Записей в блоге: 6
07.10.2014, 12:05 6
C++
1
        Run r = *(runPosition);
Какие основания, что итератор указывает на объект Run? По хорошему вам следует описать для типа Run свой набор итераторов и оперировать ими.
0
0 / 0 / 0
Регистрация: 27.03.2013
Сообщений: 15
07.10.2014, 13:11  [ТС] 7
Цитата Сообщение от Ilot Посмотреть сообщение
Какие основания, что итератор указывает на объект Run?
Я считал, что такой вызов функции является основанием:
C++
1
GetRun(runs.end() - subtrahend - 1)
Я не прав?

Цитата Сообщение от Ilot Посмотреть сообщение
По хорошему вам следует описать для типа Run свой набор итераторов и оперировать ими.
Не потеряется ли в таком случае смысл в использовании RandomAccessIterator? И возможно ли тогда будет приводить RandomAccessIterator к какому-то RunIterator и наоборот при необходимости?
0
Эксперт по математике/физикеЭксперт С++
2048 / 1366 / 395
Регистрация: 16.05.2013
Сообщений: 3,506
Записей в блоге: 6
07.10.2014, 13:15 8
maked0n, если итератор используется классом Rum то почему вы его не инкапсулируете в этот класс?
Итератор предоставляется классом с которым он работает. Посмотрите реализацию любого итератора в контейнерах stl.
0
07.10.2014, 13:15
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.10.2014, 13:15
Помогаю со студенческими работами здесь

Использование потоковых итераторов
Вот код:#include&lt;iostream&gt; #include&lt;vector&gt; #include&lt;algorithm&gt; #include&lt;iterator&gt; using...

Не видит класс итераторов
Предметная область: Множество натуральных чисел, Реализованное через Хеш таблицы С цепочками. В...

Потоки и запоминание итераторов
Жду помощи... хочу, чтобы 2 потока запоминали итераторы, чтобы потом можно было свапнуть...

Сравнение итераторов list
Я хочу скопировать из str какой-то произвольный диапазон значений, проблема в том что я могу выйти...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru