0

我正在尝试从 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;
}

我收到unknown type name错误reference,pointerdifference_type.

4

1 回答 1

4

标准库中已经有std::iterator_traits<iterator>了。您using namespace std;使标题中的内容与用户定义的内容一起可见。从代码中删除。 using namespace std;

另一个大问题是像这里这样的地方:reference operator*(). 使用模板,当您使用reference编译器时,编译器只会在里面Checked_iter查看它是否存在。您需要像这样完全限定它:typename iterator_traits<Iter>::reference operator*()或使用所谓的注入类名,即typename Checked_iter::reference operator*()。否则,编译器会告诉你它不存在。顺便说一句,reference等等就是所谓的从属名称

修复上述错误后,您将需要包含<stdexcept>getstd::out_of_range等。并在所有内容前面加上std::.

此外, in difference_type index() {return curr-c.begin();},c是一个指针,因此您需要更改为c->begin().

很多错误......我有一个可编译的程序

#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;
}
于 2013-04-01T03:23:31.060 回答