我从std :: iterator继承,但编译器无法识别'pointer'或'reference'

时间:2015-11-01 15:03:13

标签: c++ templates iterator

我正在制作自定义迭代器,但我很困惑 是什么使得编译器在模板化迭代器实现的情况下无法识别pointerreference typedef。

以下代码编译良好:

#include <iterator>

struct It : std::iterator<std::random_access_iterator_tag, int>
{
    int *v;
    pointer operator-> () { return v; }
    reference operator* () { return *v; }

};

但是一旦我将我的自定义迭代器模板化,我就会收到错误:

#include <iterator>

template <class T>
struct It2 : std::iterator<std::random_access_iterator_tag, T>
{
    T *v;
    pointer operator-> () { return v; }
    reference operator* () { return *v; }

};

whole code here

error: 'pointer' does not name a type
note: (perhaps 'typename std::iterator<std::random_access_iterator_tag, T>::pointer' was intended)
error: 'reference' does not name a type
...

1&GT;为什么编译器无法看到pointer中包含的referencestd::iterator定义?

根据note,似乎我不应该使用std :: iterator结构,但我应该手动复制typedef。 但是,如果迭代器或iterator_traits将来获得额外的typedef,那么这似乎太容易出错。

2。您认为我应该如何处理这些特征的定义(pointerreference等)?

3 个答案:

答案 0 :(得分:6)

  

1&GT;为什么编译器不能看到std :: iterator中包含的指针和引用定义?

因为编译器不能排除您尝试提供std::iterator的特殊化,其中pointerreference不是类型定义,所以从属名称永远不能被解释为{ {1}}在模板定义时。

  

的2。您认为我应该如何处理这些特征的定义(指针,参考等)?

虽然每次使用typedef明确限定它们,但您可以做的是将它们声明为一次,并依赖于typename定义的其余部分中的那个声明:

It2

答案 1 :(得分:5)

现在您的基类是dependent type,其成员pos = (y-1) * width + x pointer也是如此。

你需要:

  • 向编译器表明这些单词是
  • 类型
  • 向编译器表明这些单词是成员类型

您可以轻松完成:

reference

为什么呢?因为C ++很古怪,因为它非常简单。

答案 2 :(得分:1)

编译器非常清楚错误:

  

可能是typename std::iterator<std::random_access_iterator_tag, T>::pointer

因为pointer已成为类型相关的名称。