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

Checked_iter - C++

Восстановить пароль Регистрация
 
 
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
25.07.2013, 04:13     Checked_iter #1
Здорова господа!
Я тут пытаюсь создать свой Checked_iter, вот код который из книги набрал вроде кое-как работает:
Кликните здесь для просмотра всего текста
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
//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;
 
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();//элемент не находится в последовательности выход
    }
 
    //оператор сравнения
    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
    {
        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
        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])
};
 
int main()
{
    cout <<"Chacked_iter"<<endl;
    list<string> ls;
    ls.push_back("hellow");
    ls.push_back("world");
 
    Checked_iter<list<string> > p(ls,ls.begin());
    try
    {
        cout <<*p<<endl;
        ++p;
        cout <<*p<<endl;
        ++p;
        cout <<*p<<endl;
    }
    catch(out_of_bounds)
    {
        cout <<"event be except"<<endl;
    }
 
    return 0;
}


И тут повозникало немножко вопросов:
C++
1
2
3
4
5
reference operator[](difference_type d)const//только для итераторов произвольного доступа
    {
        if(c->end()-curr<=d||d<-(curr-c->begin()))throw out_of_bounds();
        return curr[d];
    }
Вот этот кусок кода не сильно понятен. Вот что такое difference_type???? Я так думаю это какой то typedef из iterator_traits, да и вообще что такое iterator_traits???? Это я как бы понял если мы наследуем от iterator, то мы указываем одну из категорий итераторов, а когда от iterator_traits???? Он просто на фонарь сам определяет какой у нас итератор? То есть как бы содержит в себе все типы итераторов.

Вот эта строчка несильно понятна
C++
1
2
if(c->end()-curr<=d||d<-(curr-c->begin()))throw out_of_bounds();
        return curr[d];
с->end()-curr тут вроде ясно должно вернутся int да и вообще не ясно что будет если от конца последовательности отнять текущий итератор? Я знаю что будет если от итератора который указывает допустим на третий элемент отнять указатель на начало, то вернется 2 (или 3).

Еще вот эта вот штуковина
C++
1
struct out_of_bounds{};
Это я уже сам ее определил, потому что не нашел в <stdexcept> и в <exception> out_of_bounds. Его наверное нужно самому определять?

Еще к этому итератору самому нужно добавить операции +,-,< и т.д.
Вот как мне это сделать? Что под операцией '+' понимается для итераторов? Это что мне нужно, если допустим один итератор указывает на второй элемент, а другой на третий, то когда я прибавлю один итератор к другому у меня должен получится третий итератор который будет указывать на пятый элемент (2+3) ??? А операция '<' это что если it1 указывает на второй элемент, а it2 на третий, то когда it1<it2 должно вернутся true?????

Добавлено через 25 минут
C++
1
d<-(curr-c->begin())
Тут строчка не сильно ясна, это что унарный минус???
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.07.2013, 04:13     Checked_iter
Посмотрите здесь:

C++ Checked_Iter

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11811 / 6790 / 767
Регистрация: 27.09.2012
Сообщений: 16,845
Записей в блоге: 2
Завершенные тесты: 1
25.07.2013, 06:38     Checked_iter #2
Цитата Сообщение от ninja2 Посмотреть сообщение
да и вообще что такое iterator_traits?
Долго посмотреть?
http://www.cplusplus.com/reference/i...erator_traits/
Цитата Сообщение от ninja2 Посмотреть сообщение
От что такое difference_type?
Ответ по ссылке выше
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
25.07.2013, 10:03     Checked_iter #3
C++
1
if(c->end()-curr<d||d<-(curr-c->begin()))throw out_of_bounds();
Данная строчка эквивалетна

C++
1
if (c->end() - curr < d || d < -(curr - c->begin())) throw out_of_bounds();
Полагаю, так понятнее.
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
26.07.2013, 03:44  [ТС]     Checked_iter #4
ForEveR, Да понятно а от арифметические операции над указателями, итератор это можно сказать указатель, от есть у нас int* p. Первый элемент допустим указывает на 2000, второй на 2004, третий на 2008, от если мы отнимим от второго первый элемент(2004-2000) мы должны получить 4, а на самом деле мы ж получим 1. Так что получается оно само автоматом делит на 4. Это примерчик из какой то книги или статьи, не помню, про арифметику указателей.
Цитата Сообщение от Croessmah Посмотреть сообщение
Долго посмотреть?
Да смотрел и не раз, токо там мало что понял, токо глянул вроде понятнее стало, но все рамно зачем он используется, затем чтобы задать обобщенный тип? iterator используется для того чтобы задать какой то определенный тип итератора, а iterator_traits (черты итератора) чтобы задать как бы все итераторы?
Он походу так же используется как и unique_function, для того чтобы просто задать имена typedef с известными именами

Добавлено через 15 часов 41 минуту
ЕСть еще задание: "Переделайте Checked_iter так, чтобы проверять недействительные итераторы."
Как его сделать? Недействительные итераторы это когда мы создали этот итератор, а затем изменили resize() размер контейнера и некоторые итераторы могут стать недействительными. Как же мне это сделать? Нужно наверно в каждом методе, разыменование, инкремент, декремент перепроверять диапазон? В книге нету примера, нужно самому додумать.
Давайте попытаемся просто теоретически разобрать, без кода!!!!

Добавлено через 7 минут
От код, который не работает так как нужно.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    try
    {
        cout <<*p<<endl;
        ++p;
        //ls.resize(2);
        cout <<*p<<endl;
        ++p;
        ls.resize(2);//делает p недействительным
        cout <<*p<<endl;
        //cout <<"p-p1 = "<<(p-p1)<<endl;
 
    }
    catch(out_of_bounds)
    {
        cout <<"event be except"<<endl;
    }
 
    return 0;
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
26.07.2013, 09:15     Checked_iter #5
ninja2, Ну да, просто проверить диапазон, в чем проблема?
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
26.07.2013, 09:50     Checked_iter #6
Цитата Сообщение от ninja2 Посмотреть сообщение
(2004-2000) мы должны получить 4, а на самом деле мы ж получим 1. Так что получается оно само автоматом делит на 4.
В общем случае разница считается в кол-ве элементов типа, на который указывает итератор, а не в кол-ве байт.
Цитата Сообщение от ninja2 Посмотреть сообщение
iterator_traits (черты итератора) чтобы задать как бы все итераторы?
Т.к. итераторы не обязаны наследовать от единого базового класса (а порой "итератор" и вовсе не является классом), в стандартную библиотеку введен (шаблонный) тип iterator_traits, который является хранилищем свойств того или иного итератора. Это позволяет писать алгоритмы, опираясь на iterator_traits<класс_итератора>.
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
26.07.2013, 12:23  [ТС]     Checked_iter #7
Цитата Сообщение от 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>" (или приемлемое преобразование отсутствует)"
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
26.07.2013, 13:15     Checked_iter #8
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
#include <vector>
#include <iostream>
#include <exception>
#include <stdexcept>
 
template<typename Container, typename Iterator = typename Container::iterator>
class checked_iterator
{
public:
   checked_iterator(Container& cnt, Iterator pos) :
      container_(&cnt), position_(pos)
   {
   }
   checked_iterator(const checked_iterator& rhs) :
      container_(&rhs.container_), position_(rhs.position_)
   {
   }
   checked_iterator& operator ++()
   {
      check_valid();
      ++position_;
      return *this;
   }
   checked_iterator operator ++ (int)
   {
      checked_iterator tmp(*this);
      this->operator ++();
      return tmp;
   }
   typename Container::const_reference operator * () const
   {
      return const_cast<typename Container::reference>
      (const_cast<checked_iterator&>(*this).operator *());
   }
   typename Container::reference operator * ()
   {
      check_valid();
      return *position_;
   }
   friend bool operator == (const checked_iterator& first, const checked_iterator& second)
   {
      return first.container_ == second.container_ && first.position_ == second.position_;
   }
   friend bool operator != (const checked_iterator& first, const checked_iterator& second)
   {
      return !(first == second);
   }
private:
   void check_valid() const
   {
      for (typename Container::const_iterator pos = container_->begin(); pos != container_->end(); ++pos)
      {
         if (pos == position_)
         {
            return;
         }
      }
      throw std::out_of_range("invariant failed");
   }
 
   Container* container_;
   Iterator position_;
};
 
int main()
{
   std::vector<int> vec = {1,2,3,4};
   checked_iterator<std::vector<int> > c_begin(vec, vec.begin()), c_end(vec, vec.end());
   for (; c_begin != c_end; ++c_begin)
   {
      std::cout << *c_begin << std::endl;
   }
   checked_iterator<std::vector<int> > next_c_begin(vec, vec.begin());
   vec.resize(100);
   try
   {
      for (; next_c_begin != c_end; ++next_c_begin)
      {
         std::cout << *next_c_begin << std::endl;
      }
   }
   catch (const std::exception& e)
   {
      std::cout << e.what() << std::endl;
   }
}
Bash
1
2
3
4
5
6
./new
1
2
3
4
invariant failed
Если проверка на равенство не работает - значит используется debug режим, в котором свои checked итераторы. Итераторы нельзя выводить в поток. Можно вывести либо адрес итератора, либо адрес элемента на который указывает итератор (совсем не факт, что сработает, если итератор инвалидировался). Можно сделать еще один вариант, сохранять после каждой операции размер контейнера/адрес буфера, и в check_valid просто проверять, что они до сих пор совпадают.
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
26.07.2013, 17:35  [ТС]     Checked_iter #9
ForEveR, У меня код не запускается. Я его чуток подредактировал под visual studio 2010
Кликните здесь для просмотра всего текста
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
#include <vector>
#include <iostream>
#include <exception>
#include <stdexcept>
 
template<typename Container, typename Iterator = typename Container::iterator>
class checked_iterator
{
public:
   checked_iterator(Container& cnt, Iterator pos) :
      container_(&cnt), position_(pos)
   {
   }
   checked_iterator(const checked_iterator& rhs) :
      container_(&rhs.container_), position_(rhs.position_)
   {
   }
   checked_iterator& operator ++()
   {
      check_valid();
      ++position_;
      return *this;
   }
   checked_iterator operator ++ (int)
   {
      checked_iterator tmp(*this);
      this->operator ++();
      return tmp;
   }
   typename Container::const_reference operator * () const
   {
      return const_cast<typename Container::reference>
      (const_cast<checked_iterator&>(*this).operator *());
   }
   typename Container::reference operator * ()
   {
      check_valid();
      return *position_;
   }
   friend bool operator == (const checked_iterator& first, const checked_iterator& second)
   {
      return first.container_ == second.container_ && first.position_ == second.position_;
   }
   friend bool operator != (const checked_iterator& first, const checked_iterator& second)
   {
      return !(first == second);
   }
private:
   void check_valid() const
   {
       //std::cout <<"Mu tyt"<<std::endl;
      for (typename Container::const_iterator pos = container_->begin(); pos != container_->end(); ++pos)
      {
        //  pos==position_;
          std::cout <<"Mu tyt"<<std::endl;
          std::cout <<"*pos= "<<*pos<<' '<<"*position_= "<<*position_<<std::endl;
         if (pos == position_)
         {
            return;
         }
      }
      throw std::out_of_range("invariant failed");
   }
 
   Container* container_;
   Iterator position_;
};
 
int main()
{
    int mass[]={1,2,3,4};
   std::vector<int> vec(mass,mass+4);
   checked_iterator<std::vector<int> > c_begin(vec, vec.begin()), c_end(vec, vec.end());
   for (; c_begin != c_end; ++c_begin)
   {
      std::cout << *c_begin << std::endl;
   }
   checked_iterator<std::vector<int> > next_c_begin(vec, vec.begin());
   vec.resize(100);
   try
   {
       std::cout <<"Perexodim k cikly"<<std::endl;
       next_c_begin!=c_end;//тут сразу выбрасывается ошибка
       std::cout <<"nex_c_begin!=c_end"<<std::endl;//эта строчка не выведется
      for (; next_c_begin != c_end; ++next_c_begin)
      {
          std::cout <<"Mu eje v cikle"<<std::endl;
         std::cout << *next_c_begin << std::endl;
      }
   }
   catch (const std::exception& e)
   {
      std::cout << e.what() << std::endl;
   }
}


В этой строчке ошибка.
C++
1
next_c_begin!=c_end;//тут сразу выбрасывается ошибка
Миниатюры
Checked_iter  
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
26.07.2013, 17:39  [ТС]     Checked_iter #10
Что это значит у меня дебаг режим работает?
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
26.07.2013, 17:40     Checked_iter #11
Цитата Сообщение от ninja2 Посмотреть сообщение
Что это значит у меня дебаг режим работает?
Да.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
26.07.2013, 17:43     Checked_iter #12
ninja2, А то, что там написано DEBUG Assertion Failed ничего не говорит?
Можно просто сделать итераторы MSVC unchecked - как написано в гугле.
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
26.07.2013, 17:45  [ТС]     Checked_iter #13
ForEveR, check_valid тоже делает что и моя valid1, обход вектора и сравнивает указатели.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
26.07.2013, 17:46     Checked_iter #14
ninja2, Да, и что далее? Отключите дебаг режим/отключите checked итераторы.
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
26.07.2013, 17:47  [ТС]     Checked_iter #15
gray_fox, А можно в визуал студио просто скомпилировать программу без дебага? Я просто контр ф5 нажимаю это с дебагом походу, а без дебага? Мб скомпилируется, а затем запустю посмотрю результат.

Добавлено через 24 секунды
ForEveR, А как его отключить я не знаю?
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
26.07.2013, 17:49     Checked_iter #16
Цитата Сообщение от ninja2 Посмотреть сообщение
gray_fox, А можно в визуал студио просто скомпилировать программу без дебага?
:/ ну измени кофигурацию проекта на Release...

Добавлено через 47 секунд
либо там есть какой-нибудь весёлый макрос, что бы отключить checked iterators
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
26.07.2013, 17:52  [ТС]     Checked_iter #17
Цитата Сообщение от gray_fox Посмотреть сообщение
:/ ну измени кофигурацию проекта на Release...
Изменил на Release, скомпилировалось, только я забыл добавить что б программа не закрывалась cin, возможно и сработала. Токо окно командная строка открылась пустая и не закрывается как зависло, ни на шо не реагирует пустое.
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
26.07.2013, 17:55     Checked_iter #18
Гуру С++, http://msdn.microsoft.com/en-us/libr...vs.110%29.aspx
Checked iterators apply to release builds and debug builds.
For information on how to disable warnings generated by checked iterators, see _SCL_SECURE_NO_WARNINGS.
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
26.07.2013, 17:58  [ТС]     Checked_iter #19
gray_fox, а не знаешь оно так и должно зависать? Просто второй раз уже при релиз скомпилировать нельзя пишет, что программа открыта, а закрыть ее не могу, ни снять задачу ни снять процесс. Щас наверно перезагружу или попробую визуал студио заново перезапустить.
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
26.07.2013, 18:04     Checked_iter #20
Цитата Сообщение от ninja2 Посмотреть сообщение
gray_fox, а не знаешь оно так и должно зависать? Просто второй раз уже при релиз скомпилировать нельзя пишет, что программа открыта, а закрыть ее не могу, ни снять задачу ни снять процесс. Щас наверно перезагружу или попробую визуал студио заново перезапустить.
Не знаю, у меня нет сейчас VS...
Yandex
Объявления
26.07.2013, 18:04     Checked_iter
Ответ Создать тему
Опции темы

Текущее время: 11:13. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru