C++ C++;类迭代器实用程序:定义和用法

C++ C++;类迭代器实用程序:定义和用法,c++,class,templates,iterator,typename,C++,Class,Templates,Iterator,Typename,我有一个名为a的类,在这个类中我有一个iterable容器,我会按照一些访问规则迭代它——顺序、空性和其他 为了简化下面的示例,让我们考虑一下我正在迭代容器,但是使用内置容器的迭代器不能完成 > 。 迭代器通常是如何定义的,因为向量迭代器不需要typename标记?它是否与从类定义而不是从向量本身声明向量有关 std::vector<int> v; for (std::vector<int>::iterator it(v.begin()); it != v.end();

我有一个名为
a
的类,在这个类中我有一个iterable容器,我会按照一些访问规则迭代它——顺序、空性和其他

为了简化下面的示例,让我们考虑一下我正在迭代容器,但是使用内置容器的迭代器不能完成<强> >

  • 迭代器通常是如何定义的,因为向量迭代器不需要
    typename
    标记?它是否与从类定义而不是从向量本身声明向量有关

    std::vector<int> v;
    for (std::vector<int>::iterator it(v.begin()); it != v.end(); ++it) {
    }
    
    std::vector v;
    for(std::vector::iterator it(v.begin());it!=v.end();++it){
    }
    
  • 迭代器是在容器类中定义的吗?我猜它是命名为composition?或者,如果不是,迭代器是如何添加到类的命名空间的,如:

    std::vector<int>::iterator it;
    
    std::vector::iterator;
    
  • 1-为什么我必须使用
    typename
    时:[……]

    您不必使用
    typename
    。使用依赖的限定类型名时,模板中需要使用
    typename
    消歧器。这:

    是<强>非法< /强> C++。如果

    A
    不是模板参数的名称,则只需执行以下操作:

    A::iterator it;
    
    如果您在模板中,并且
    a
    是模板参数的名称,例如:

    template<typename A>
    struct X
    {
        void foo()
        {
            typename A::iterator it;
        //  ^^^^^^^^
        //  This is necessary here!
        }
    };
    
    std::vector<int>::iterator it; // "typename" not required
    
    然后不需要
    typename
    ,因为在
    A::iterator it
    中不需要它。但是,如果您位于模板内,如以下情况所示,则需要该模板:

    template<typename A>
    struct X
    {
        void foo()
        {
            typename std::vector<A>::iterator it;
        //  ^^^^^^^^
        //  This is necessary here!
        }
    };
    
    模板
    结构X
    {
    void foo()
    {
    typename std::vector::iterator;
    //  ^^^^^^^^
    //这在这里是必要的!
    }
    };
    
    这是因为这里有一个限定的、依赖的类型名


    3-迭代器是在容器类中定义的吗?我猜它是命名为composition的,或者,如果不是,迭代器是如何添加到类的名称空间的,如[…]

    这可以通过定义嵌套类来实现,也可以通过使用类型别名来实现:

    template<typename T>
    struct X
    {
        typedef T* iterator;
        iterator begin() { /* ... */ }
        // ...
    };
    
    X<int>::iterator it; // OK: "typename" not required
    
    template<typename T>
    void foo(X<T>& x)
    {
        typename X<T>::iterator it = x.begin();
    //  ^^^^^^^^
    //  This is necessary here!
    
        // ...
    }
    
    模板
    结构X
    {
    typedef T*迭代器;
    迭代器begin(){/*…*/}
    // ...
    };
    X::迭代器;//确定:不需要“typename”
    模板
    void foo(X&X)
    {
    typename X::iterator it=X.begin();
    //  ^^^^^^^^
    //这在这里是必要的!
    // ...
    }
    
    您的示例代码有很多问题,因此这可能是您正在寻找的答案(waves hand):)当然,如果您的示例不正确,那么所有赌注都将被取消

    我感到惊讶的是,这一切都会起作用。”“a”是变量,“a”是类

    另外,在使用默认构造函数声明变量时,不使用结束括号()

    此外,迭代器是在容器类中定义的。只有在处理模板时,以及只有在访问可以解释为静态成员或函数/嵌套类或typedef的内容时,才有必要使用typename。安迪·普劳尔也给出了答案,这可以进一步解释


    祝你好运(1):你为什么用
    a::iterator
    而不是
    a::iterator
    ?@lucasmrod不确定;我想这是我的第一次尝试,因为我不知道到底发生了什么x=+1哇!非常清楚!现在我明白了为什么
    std::vector::iterator
    不需要
    typename
    。是的,我实际上使用了
    模板
    s作为
    A::iterator
    ,我不知道
    A::iterator
    是非法的,因为它非常有效(:现在,我将用您的解释美化我的迭代器定义;我正在做一个DFS迭代器,这样看起来非常整洁^^^谢谢您的回复!对不起!我刚刚检查过,是的,我使用的是类名本身,而不是实例。我使用了类似于:
    typename Node::iterator it(…)
    。只需添加此信息,以免混淆其他人^^^您帮了我很多忙!(:我想知道:我怎么会有一个
    操作符++()
    这将调用迭代器?我想,在这种特殊情况下,只有类方法才能解决这个问题,对吗?+1非常抱歉,我应该先检查它;实际上,我得到的是
    typename a::iterator it
    。我刚刚更新了它;感谢您的回复!
    std::vector<int>::iterator it; // "typename" not required
    
    template<typename A>
    struct X
    {
        void foo()
        {
            typename std::vector<A>::iterator it;
        //  ^^^^^^^^
        //  This is necessary here!
        }
    };
    
    template<typename T>
    struct X
    {
        typedef T* iterator;
        iterator begin() { /* ... */ }
        // ...
    };
    
    X<int>::iterator it; // OK: "typename" not required
    
    template<typename T>
    void foo(X<T>& x)
    {
        typename X<T>::iterator it = x.begin();
    //  ^^^^^^^^
    //  This is necessary here!
    
        // ...
    }
    
    A a;
    A::iterator it;
    for (A::iterator it; it != ...; ++it) {
    }