Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
maked0n
0 / 0 / 0
Регистрация: 27.03.2013
Сообщений: 15
#1

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

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

Доброго времени суток. Пишу 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.10.2014, 23:19
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Конфликт итераторов (C++):

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

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

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

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

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

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

7
DrOffset
7518 / 4514 / 1097
Регистрация: 30.01.2014
Сообщений: 7,362
06.10.2014, 23:21 #2
Цитата Сообщение от maked0n Посмотреть сообщение
Что я делаю не так?
Метод at() у std::vector принимает индекс (size_t), а не итератор.
0
maked0n
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
DrOffset
7518 / 4514 / 1097
Регистрация: 30.01.2014
Сообщений: 7,362
06.10.2014, 23:39 #4
Цитата Сообщение от maked0n Посмотреть сообщение
Ведь runPosition, на сколько я понимаю, не будет "принадлежать" этому контейнеру.
Нужно больше кода.
Если итератор получен у контейнера, он "принадлежит" ему так или иначе.

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

Добавлено через 1 минуту
PS. путаница с итераторами должна уйти, если начать воспринимать итератор как указатель на элемент.
0
maked0n
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
Ilot
Эксперт С++
1826 / 1184 / 342
Регистрация: 16.05.2013
Сообщений: 3,119
Записей в блоге: 5
Завершенные тесты: 1
07.10.2014, 12:05 #6
C++
1
        Run r = *(runPosition);
Какие основания, что итератор указывает на объект Run? По хорошему вам следует описать для типа Run свой набор итераторов и оперировать ими.
0
maked0n
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
Ilot
Эксперт С++
1826 / 1184 / 342
Регистрация: 16.05.2013
Сообщений: 3,119
Записей в блоге: 5
Завершенные тесты: 1
07.10.2014, 13:15 #8
maked0n, если итератор используется классом Rum то почему вы его не инкапсулируете в этот класс?
Итератор предоставляется классом с которым он работает. Посмотрите реализацию любого итератора в контейнерах stl.
0
07.10.2014, 13:15
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.10.2014, 13:15
Привет! Вот еще темы с решениями:

Равенство пустых итераторов
Гарантировано ли для стандартных контейнеров равенство пустых итераторов?...

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

Копирование файла с использованием итераторов
Задание: Напишите программу, копирующую один файл с целочисленными данными в...

Сравнение прямых и обратных итераторов
Добрый вечер! Делаю следующие задание: &quot;Используйте одни прямой и одни...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru