C++ 类迭代器实用程序 : definition and usage

标签 c++ class templates iterator typename

我有一个名为 A 的类,在这个类中我有一个可迭代容器,我按照一些访问规则(顺序、空性等)对它进行迭代。

为了简化以下示例,我们假设我只是在容器中进行迭代,但这无法使用内置容器的迭代器来完成。

class A {
public:
    class iterator {
    public:
        // Constructor
        iterator() {
        }
        // Destructor
        ~iterator() {
        }
        // Advances the iterator
        void operator++() {
           // Some accessing policy
        }
    };
private:
    std::vector<int> a;
};

一切都工作得非常好——而且看起来非常整洁——除了,当我声明我的迭代器时,我必须使用typename——我几乎认为它是为了告诉编译器我拥有的是类型,而不是类实例化本身。

问题:

  1. 为什么我必须使用typename:

    A a;
    for (typename A::iterator it(...); it != ...; ++it) {
    }
    
  2. 由于 vector 迭代器不需要 typename 标记,因此通常如何定义迭代器?它是否与从类定义中声明 vector 有关,而不是从 vector 本身声明 vector ?

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

    std::vector<int>::iterator it;
    

最佳答案

1 - why do I have to use typename when I do: [...]

您不必使用typenametypename当您使用依赖的限定类型名称时,模板内需要消歧器。 This Q&A on StackOverflow clarifies things 。这:

A a;
typename a::iterator it; // ERROR!

非法 C++。前提是A不是模板参数的名称,您应该这样做:

A::iterator it;

如果您在模板内并且 A是模板参数的名称,例如:

template<typename A>
struct X
{
    void foo()
    {
        typename A::iterator it;
    //  ^^^^^^^^
    //  This is necessary here!
    }
};

那么你必须使用typename告诉编译器 :: 后面的内容是类型的名称。


2 - How are iterators commonly defined, since a vector iterator does not require the typename tag?

再说一遍,“vector 迭代器不需要 typename 标记”是不正确的。如果您对该 vector 有明确的特化,例如:

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!
    }
};

那是因为std::vector<A>::iterator这是一个限定的依赖类型名称。


3 - Are the iterators defined inside the container class -- I guess it's named composition --, or, if not, how is it iterators are added to the namespace of a class, like in [..]

这可以通过定义嵌套类来完成,或者简单地通过使用类型别名来完成:

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!

    // ...
}

关于C++ 类迭代器实用程序 : definition and usage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15311835/

相关文章:

c++ - 模板类的继承问题

c++ - 如何将字符串转换成char *数组

Javascript "classes"(无框架)

具有非原始类型的 C++ 按值传递?

java - 什么是将 2 个类合并为 1 个类,其中一个类是另一个类的子类?

c# - 这个委托(delegate)的使用是好是坏?

c++ - 类里面的模板查找?

c# - 如何将数据从一个 UnmanagedMemoryStream 复制到另一个

c++ - 在单元安全代码中处理文字零

c++ - 这是 g++ 和 clang++ 优化的错误吗?