简体   繁体   English

检查的迭代器不起作用

[英]Checked iterator not working

I'm trying to run the checked iterator example from the c++ programming language (3rd edition) book, but I'm getting errors, and I think I need some help understanding, why I'm getting these errors, I'm getting the code from the book, thanks in advance. 我正在尝试从c ++编程语言(第3版)书中运行经过检查的迭代器示例,但是我遇到了错误,我想我需要一些帮助来理解为什么我会出现这些错误,书中的代码,在此先感谢。

#include <iostream>
#include <vector>
#include <iterator>
#include <exception>
#include <cstddef>

// using namespace std;

template<class Iter> struct iterator_traits{
    typedef typename Iter::iterator_category iterator_category;
    typedef typename Iter::value_type value_type;
    typedef typename Iter::difference_type difference_type;
    typedef typename Iter::pointer pointer;
    typedef typename Iter::reference reference;
};

// specialization for pointer
//template<class T> struct iterator_traits<T*>
//{
//    typedef ptrdiff_t difference_type;
//    typedef T value_type;
//    typedef T* pointer;
//    typedef T& reference;
//    typedef std::random_access_iterator_tag iterator_category;
//};


template<class Cat, class T, class Dist=ptrdiff_t, class Ptr=T*, class Ref=T&>
struct iterator{
    typedef Cat iterator_category;
    typedef T value_type;
    typedef Dist difference_type;
    typedef Ptr pointer;
    typedef Ref reference;
};

template<class Ran>
typename iterator_traits<Ran>::difference_type dist_helper(Ran first, Ran last, random_access_iterator_tag)
{
    return last-first;  //rely on random access

}
template<class In >
typename iterator_traits<In>::difference_type distance(In first, In last)
{
    return dist_helper(first, last, iterator_traits<In>::iterator_category());

}


//Code
template <class Cont, class Iter=typename Cont::iterator>
class Checked_iter : public iterator_traits<Iter>{   //deriving from iterator_traits
    Iter curr;
    Cont* c;
//....

public:
    void valid(Iter p)
    {
        if ( c->end() == p)
            return;
        for(Iter pp= c->begin(); pp != c->end(); ++pp){
            if (pp==p)
                return;
        }
        throw std::out_of_range("out of range");
    }
    friend bool operator==(const Checked_iter& i, const Checked_iter& j)
    {
        return i.c == j.c && i.curr == j.curr;
    }
    //no default initialzer
    //use defaul t copy constructor and cop assignment.

    Checked_iter(Cont& x, Iter p):c(&x), curr(p) {valid(p);}


    //Error:Unkown type name "reference"
    reference operator*()
    {
        if (curr == c->end()) throw std::out_of_range("out of range");
        return *curr;
    }

    //Error:Unkown type name "pointer"
    pointer operator->()
    {
        return &*curr;                    // checked by *
    }
    //Error:Unkown type name "difference_type"
    Checked_iter operator+(difference_type d )        // for random access iterators only
    {
        if(c->end() - curr <= d )
            throw std::out_of_range("out of range");
        return Checked_iter(c ,curr+d );
    }

    //Error:Unkown type name "difference_type"
    reference operator[](difference_type d )      // for random access iterators only
    {
        if (c->end() - curr <= d)
            throw std::out_of_range("out of range");
        return c[d];
    }

    Checked_iter& operator++()             // prefix ++
    {
        if (curr == c->end())
            throw std::out_of_range("out of range");
        ++curr;
        return *this ;
    }

    Checked_iter& operator++(int)
    {
        Checked_iter tmp= *this;
        ++*this; //Checked by prefix ++
        return tmp;
    }

    Checked_iter& operator--()    //prefix--
    {
        if(curr == c->begin())
            throw std::out_of_range("out of range");
        --curr;
        return *this;

    }

    Checked_iter& operator--(int)   //postfix
    {
        Checked_iter tmp=*this;
        --*this;       //checked by prefix --
        return tmp;

    }

   //Error:Unkown type name "difference_type"
    difference_type index() {return curr-c.begin();}  //random access only
    Iterator unchecked() {return curr;}
    //+-<
};

template<class Cont, class Iter> Checked_iter<Cont,Iter>make_checked(Cont& c, Iter i)
{
    return Checked_iter<Cont, Iter>(c,i);

}
template<class Cont>Checked_iter<Cont,typename Cont::iterator>make_checked(Cont& c)
{
    return Checked_iter<Cont, typename Cont::iterator>(c,c.begin());
}


void f_count(vector<int>& vec)
{
    int count=0;
    try{
        Checked_iter<vector<int>> p(vec, vec.begin());
        while(true){
            ++p;
            ++count;
        }
    }
    catch(out_of_range){
        cout<<"overrun after"<<count<<"tries\n";
    }
}

void test_f(){
    int a[] = {0,1,2,3,4,5,6,7,8,9};
    vector<int> l(a, a+sizeof(a)/sizeof(int));
    print_v(l);
    f_count(l);
}

void print_v(vector<int>vec)
{
    for(aut i=vec.begin();i != vec.end(); ++i)
        cout<<*i<<" ";
}

int main()
{
    test_f();

    return 0;
}

I'm getting unknown type name error for reference , pointer and difference_type . 我收到了unknown type name错误,用于referencepointerdifference_type

There already is std::iterator_traits in the standard library in <iterator> . <iterator>中的标准库中已经存在std :: iterator_traits Your using namespace std; 您正在using namespace std; makes the one in the header visible along with your user defined one. 使标题中的一个与用户定义的一个一起可见。 Remove using namespace std; using namespace std; 删除 using namespace std; from the code. 从代码。

The other big problem is places like here: reference operator*() . 另一个大问题是这里的地方: reference operator*() With templates, when you use reference the compiler only looks inside of Checked_iter to see if it exists. 对于模板,当您使用reference ,编译器仅在Checked_iter内部查看其是否存在。 You need to fully qualify it like this: typename iterator_traits<Iter>::reference operator*() or use what is called the injected class name , ie typename Checked_iter::reference operator*() . 您需要像这样完全限定它: typename iterator_traits<Iter>::reference operator*()或使用所谓的注入类名 ,即typename Checked_iter::reference operator*() Otherwise, the compiler will tell you that it does not exist. 否则,编译器会告诉您它不存在。 BTW, reference , etc. is what is known aa dependent name . 顺便说一句, reference等是一个已知的依赖名称

Once the above errors are fixed, you will need to include <stdexcept> to get std::out_of_range , etc. And prepend everything with std:: . 解决上述错误后,您将需要包含<stdexcept>以获得std::out_of_range <stdexcept>等。并在所有内容前添加std::

Also, in difference_type index() {return curr-c.begin();} , c is a pointer , so you need to change to c->begin() . 另外,在difference_type index() {return curr-c.begin();}c指针 ,因此您需要更改为c->begin()

Lots of errors... I got a compilable program : 很多错误...我有一个可编译的程序

#include <iostream>
#include <vector>
#include <iterator>
#include <exception>
#include <cstddef>
#include <stdexcept>


template<class Iter> struct iterator_traits{
    typedef typename Iter::iterator_category iterator_category;
    typedef typename Iter::value_type value_type;
    typedef typename Iter::difference_type difference_type;
    typedef typename Iter::pointer pointer;
    typedef typename Iter::reference reference;
};

// specialization for pointer
//template<class T> struct iterator_traits<T*>
//{
//    typedef ptrdiff_t difference_type;
//    typedef T value_type;
//    typedef T* pointer;
//    typedef T& reference;
//    typedef random_access_iterator_tag iterator_category;
//};


template<class Cat, class T, class Dist=ptrdiff_t, class Ptr=T*, class Ref=T&>
struct iterator {
    typedef Cat iterator_category;
    typedef T value_type;
    typedef Dist difference_type;
    typedef Ptr pointer;
    typedef Ref reference;
};

template<class Ran>
typename iterator_traits<Ran>::difference_type dist_helper(Ran first, Ran last, std::random_access_iterator_tag)
{
    return last-first;  //rely on random access

}
template<class In >
typename iterator_traits<In>::difference_type distance(In first, In last)
{
    return dist_helper(first, last, iterator_traits<In>::iterator_category());

}


//Code
template <class Cont, class Iter=typename Cont::iterator>
class Checked_iter : public iterator_traits<Iter>{   //deriving from iterator_traits
    Iter curr;
    Cont* c;
//....
public:
    void valid(Iter p)
    {
        if ( c->end() == p)
            return;
        for(Iter pp= c->begin(); pp != c->end(); ++pp){
            if (pp==p)
                return;
        }
        throw std::out_of_range("out of range");
    }
    friend bool operator==(const Checked_iter& i, const Checked_iter& j)
    {
        return i.c == j.c && i.curr == j.curr;
    }
    //no default initialzer
    //use defaul t copy constructor and cop assignment.

    Checked_iter(Cont& x, Iter p):c(&x), curr(p) {valid(p);}

    typename iterator_traits<Iter>::reference operator*()
    {
        if (curr == c->end()) throw std::out_of_range("out of range");
        return *curr;
    }
    typename iterator_traits<Iter>::pointer operator->()
    {
        return &*curr;                    // checked by *
    }

    Checked_iter operator+(typename iterator_traits<Iter>::difference_type d )        // for random access iterators only
    {
        if(c->end() - curr <= d )
            throw std::out_of_range("out of range");
        return Checked_iter(c ,curr+d );
    }

    typename iterator_traits<Iter>::reference operator[](typename iterator_traits<Iter>::difference_type d )      // for random access iterators only
    {
        if (c->end() - curr <= d)
            throw std::out_of_range("out of range");
        return c[d];
    }

    Checked_iter& operator++()             // prefix ++
    {
        if (curr == c->end())
            throw std::out_of_range("out of range");
        ++curr;
        return *this ;
    }

    Checked_iter& operator++(int)
    {
        Checked_iter tmp= *this;
        ++*this; //Checked by prefix ++
        return tmp;
    }

    Checked_iter& operator--()    //prefix--
    {
        if(curr == c->begin())
            throw std::out_of_range("out of range");
        --curr;
        return *this;

    }

    Checked_iter& operator--(int)   //postfix
    {
        Checked_iter tmp=*this;
        --*this;       //checked by prefix --
        return tmp;

    }

    typename iterator_traits<Iter>::difference_type index() {return curr - c->begin();}  //random access only
    Iter unchecked() {return curr;}
    //+-<
};

template<class Cont, class Iter> Checked_iter<Cont,Iter>make_checked(Cont& c, Iter i)
{
    return Checked_iter<Cont, Iter>(c,i);

}
template<class Cont>Checked_iter<Cont,typename Cont::iterator>make_checked(Cont& c)
{
    return Checked_iter<Cont, typename Cont::iterator>(c,c.begin());
}


void f_count(std::vector<int>& vec)
{
    int count=0;
    try{
        Checked_iter<std::vector<int>> p(vec, vec.begin());
        while(true){
            ++p;
            ++count;
        }
    }
    catch(std::out_of_range){
        std::cout<<"overrun after"<<count<<"tries\n";
    }
}

void print_v(std::vector<int>vec)
{
    for(auto i=vec.begin();i != vec.end(); ++i)
        std::cout<<*i<<" ";
}

void test_f(){
    int a[] = {0,1,2,3,4,5,6,7,8,9};
    std::vector<int> l(a, a+sizeof(a)/sizeof(int));
    print_v(l);
    f_count(l);
}

int main()
{
    test_f();

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM