Форум программистов, компьютерный форум CyberForum.ru

Checked_iter - C++

Восстановить пароль Регистрация
Другие темы раздела
C++ Быстродействие http://www.cyberforum.ru/cpp-beginners/thread928426.html
Что лучше использовать, если быстродействие системы достаточно важно, а элемент используется часто? template <typename T> struct Point { T x, y; }; template <typename T>
C++ Не работает openmp Написал простенькую программку с распараллеливанием собрал откомпилил, но распараллеливания нет. Программка выглядит так: -------------------------------- #include <iostream> #include <omp.h> int main(int argc, char* argv) { #pragma omp parallel num_threads(4) http://www.cyberforum.ru/cpp-beginners/thread928416.html
C++ Каким образом getchar() меняет содержимое массива?
Здравствуйте! Почему-то наличие getchar(); в коде влияет на содержимое массива. Если данный код не менять - то выводит правильный результат. Результат представлен на первом скрине. Если удалить первый getchar() с 21 строки, то в результате появляется абракадабра - представлено на втором скрине. Если удалить второй getchar(), то в результате вообще получаются нули - представлено на третьем...
C++ клас myDate
Создайте класс Date, который будет содержать информацию о дате (день, месяц, год). С помощью механизма перегрузки операторов, определите операцию разности двух дат (результат в виде количества дней между датами), а также операцию увеличения даты на определенное количество дней. с++ class myDate { public: myDate(); ~myDate(); private:
C++ Не могу побороть wxDevC++ - на Hello world "Проект не откомпилирован" http://www.cyberforum.ru/cpp-beginners/thread928353.html
Хотел попробовать wxDevC++ в деле. Установил. Само собой, для начала сделал Hello, world. И вдруг выскакивает окно "Проект не откомпилирован"... и никак не поборю это дело. Текст-то классический: #include <windows.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv) { printf("Hello World!\n");
C++ Определить какое число Данная последовательность: 19, 39, 59, 79, 99, 119 ... И нужно определить, если введенное число относится к этой последовательности. Возможно ли это сделать вписав только одно условие? подробнее

Показать сообщение отдельно
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
26.07.2013, 12:23  [ТС]     Checked_iter
Цитата Сообщение от ForEveR Посмотреть сообщение
Ну да, просто проверить диапазон, в чем проблема?
А как же его проверить? Пытаюсь проверить. Написал функцию valid1()
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    void valid1()const
    {
        //if(c->end()==p)return;//если конец, то возврат
        //if(c->end()==curr)out_of_bounds();
        for(Iter pp=c->begin();pp!=c->end();++pp)
        {
// Эту стррочку когда добавляю то сразу же падает
//pp==curr;
            cout <<"(*c).size()= "<<(*c).size()<<' '<<*pp<<endl;
            if(pp==curr)
            {
                //cout <<"mu tyt "<<endl;exit(1);
                //cout <<"&pp= "<<pp<<" &p= "<<p<<endl;
                //cout <<"pp= "<<*pp<<" p= "<<*p<<endl;//exit(1);
                return;//если pp=p, то елемент найден возврат
            }
        }
        throw out_of_bounds();//элемент не находится в последовательности выход
    }
Добавляю valid1() в оператор operator*() в самом начале вызова, он проверяет текущий итератор Iter Curr входит ли он в последовательность. Послед resize() последовательности уже не возможно проверить, сразу же выбрасывается окно ошибки, падает при обращении pp==curr;

Полностью код
Кликните здесь для просмотра всего текста
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
//Chacked_iter
#include <iostream>
using std::cout;
using std::endl;
using std::cerr;
#include <list>
using std::list;
#include <string>
using std::string;
#include <vector>
using std::vector;
#include <iterator>
using std::iterator_traits;
using std::advance;
#include <cstdlib>
using std::exit;
 
struct out_of_bounds{};
 
template<class Cont,class Iter=typename Cont::iterator>
class Checked_iter : public iterator_traits<Iter>//наследует все типы итераторов
{
public:
    Iter curr;//итератор для текущей позиции
    Cont* c;//указатель на текущий элемент
    //...
 
    //проверка на валидность переданного итератора
    void valid(Iter p)const
    {
        if(c->end()==p)return;//если конец, то возврат
        for(Iter pp=c->begin();pp!=c->end();++pp) if(pp==p)return;//если pp=p, то елемент найден возврат
        throw out_of_bounds();//элемент не находится в последовательности выход
    }
 
    void valid1()const
    {
        //if(c->end()==p)return;//если конец, то возврат
        //if(c->end()==curr)out_of_bounds();
        for(Iter pp=c->begin();pp!=c->end();++pp)
        {
            //pp==curr; Эту стррочку когда добавляю то сразу же падает
            cout <<"(*c).size()= "<<(*c).size()<<' '<<*pp<<endl;
            if(pp==curr)
            {
                //cout <<"mu tyt "<<endl;exit(1);
                //cout <<"&pp= "<<pp<<" &p= "<<p<<endl;
                //cout <<"pp= "<<*pp<<" p= "<<*p<<endl;//exit(1);
                return;//если pp=p, то елемент найден возврат
            }
        }
        throw out_of_bounds();//элемент не находится в последовательности выход
    }
 
    //оператор сравнения
    friend bool operator==(const Checked_iter& i,const Checked_iter& j)
    {
        return i.c==j.c&&i.curr==j.curr;
    }
 
    //нет умолчательного инициализатора (конструктора по умолчанию)
    //конструктор предобразования
    Checked_iter(Cont& x, Iter p) :c(&x),curr(p){valid(p);}
    //конструктор копирования
    Checked_iter(Cont& x) :c(&x),curr(x.begin()){}
 
    //операция разыменования
    reference operator*()const
    {
        valid1();
        cout <<"dal6we"<<endl;
        if(curr==c->end())throw out_of_bounds();//еси текущий элемент равен консу, то генерация выхода за границы
        return *curr;//если не равен, то возврат значения по ссылке
    }
 
    //доступ через указатель
    pointer operator->() const
    {
        if(curr==c->end())throw out_of_bounds();//если текущий элемент равен концу, то генерация выхода за границы
        return &*curr;//возврат указателя на элемент
    }
 
    //операция '+'
    Checked_iter operator+(difference_type d)const//только для итераторов произвольного доступа
    {
        //тут похоже какието действия с указателями
        //если указатель на конец минус текущий указатель меньше d
        //d похоже на число которое передается для сдвига итератора
        //c->end()-curr вернет количество элементов до последнего
        //-(curr-c->begin()) 
        if(c->end()-curr<d||d<-(curr-c->begin()))throw out_of_bounds();
        return Checked_iter(c,curr+d);
    }
 
    reference operator[](difference_type d)const//только для итераторов произвольного доступа
    {
        if(c->end()-curr<=d||d<-(curr-c->begin()))throw out_of_bounds();
        return curr[d];
    }
 
    Checked_iter operator++ ()//префиксный ++
    {
        if(curr==c->end())throw out_of_bounds();
        ++curr;
        return *this;
    }
 
    Checked_iter operator++(int)//постфиксный ++
    {
        Checked_iter tmp=*this;
        ++*this;//проверяется префиксным ++
        return tmp;
    }
 
    Checked_iter operator--()//префиксный
    {
        if(curr==c->begin())throw out_of_bounds();
        --curr;
        return *this;
    }
 
    Checked_iter operator--(int)//постфиксный --
    {
        Checked_iter tmp=*this;
        --*this;//проверяется префиксным --
        return tmp;
    }
 
    difference_type index()const {return curr-c->begin();}//только произвольный доступ
    //Видимо без проверки возврат текущего итератора
    //просто типа итератора возврат
    Iter unchecked() const {return curr;}
    //+,-,< и т.д.(параграф 19.6[6])
    difference_type operator-(const Checked_iter& x)
    {
        valid(x);
        return (curr-y);
    }
};
 
int main()
{
    cout <<"Chacked_iter"<<endl;
    vector<string> ls;
    ls.push_back("hellow");
    ls.push_back("world");
    ls.push_back("gacpada");
    ls.push_back("da");
    ls.push_back("net");
    vector<string>::iterator it,it1;
    it=ls.begin();
    advance(it,3);
    //if(c->end()-curr<d||d<-(curr-c->begin()))throw out_of_bounds();
    if(ls.end()-it<2||2<-(it-ls.begin()))cout <<"don't work"<<endl;
    cout <<"*it= "<<*it<<' '<<(ls.end()-it)<<endl;
    cout <<"*it= "<<*it<<' '<<-(it-ls.begin())<<endl;
    
 
    Checked_iter<vector<string> > p(ls,ls.begin());
    Checked_iter<vector<string> > p1(ls,ls.begin());
    try
    {
        cout <<*p<<endl;
        ++p;
        //ls.resize(2);
        cout <<*p<<endl;
        ++p;
        ls.resize(2);
        cout <<"ls.size()= "<<ls.size()<<endl;
        
    //  --p;
        cout <<*p<<endl;
        //cout <<"p-p1 = "<<(p-p1)<<endl;
 
    }
    catch(out_of_bounds)
    {
        cout <<"event be except"<<endl;
    }
 
    return 0;
}


Добавлено через 20 минут
При resize выделяется новая область памяти под vector и мб сам Cont* c;//указатель на текущий элемент
становится уже не действительным, хотя он не вызывает ошибки да и наверно наврятли с это просто указывает на объект в котором находятся указатели, которые resize() поменяла, поэтому скорее всего ошибки тут не должно быть, смутно все так представляется. С Cont* c все в порядке нету ошибки. Я еще проверил функцией чтобы наверняка:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void valid1()const
    {
        //if(c->end()==p)return;//если конец, то возврат
        //if(c->end()==curr)out_of_bounds();
        for(Iter pp=c->begin();pp!=c->end();++pp)
        {
            //pp==curr; Эту стррочку когда добавляю то сразу же падает
            cout <<"(*c).size()= "<<(*c).size()<<' '<<*pp<<endl;
            /*if(pp==curr)
            {
                //cout <<"mu tyt "<<endl;exit(1);
                //cout <<"&pp= "<<pp<<" &p= "<<p<<endl;
                //cout <<"pp= "<<*pp<<" p= "<<*p<<endl;//exit(1);
                return;//если pp=p, то елемент найден возврат
            }*/
        }
        return;
        throw out_of_bounds();//элемент не находится в последовательности выход
    }
ошибки нету c выводится нормально

Тогда остается Iter curr. Указывает на какой то адрес. После resize() что происходит с этим указателем?
В примере он указывает на третий элемент. Происходит resize() элементы перекопировались в новую область памяти, а curr остался указывать на старую область памяти, которая уж не находится в последовательности. И почему же тогда при pp==curr возникает ошибка, если curr хранит в себе просто недействительный адрес?

Добавлено через 5 минут
Да и от когда я делаю resize(2) то тогда только указатель недействительный, а если я делаю resize(3), то у меня почему то указатель действительный. Почему? Должен же стать недействительный ведь новая область памяти выделена, а указатель указывает на старую. От я даже уже и для resize(4) попробовал то же самое происходит никакой новой памяти не выделяется, если б выделялась, то указатели становились бы недействительные???
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    try
    {
        cout <<*p<<endl;
        ++p;
        //ls.resize(2);
        cout <<*p<<endl;
        ++p;
        ls.resize(4);
        cout <<"ls.size()= "<<ls.size()<<endl;
        
    //  --p;
        cout <<*p<<endl;
        //cout <<"p-p1 = "<<(p-p1)<<endl;
 
    }
    catch(out_of_bounds)
    {
        cout <<"event be except"<<endl;
    }
Добавлено через 7 минут
И вообще когда я пытаюсь посмотреть адрес на который указывают итераторы у меня не получается их вывести. Я делаю так cout <<curr<<' '<<pp<<endl;

ошибка: "c:\test\test\test\main.cpp(42): error C2679: бинарный "<<": не найден оператор, принимающий правый операнд типа "const std::_Vector_iterator<_Myvec>" (или приемлемое преобразование отсутствует)"
 
Текущее время: 16:05. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru