为什么我不能对模板使用 std::iterator<>::reference?

Why can't I use std::iterator<>::reference with templates?

我试过这样做

template <class V>
class myiterator: std::iterator<std::random_access_iterator_tag, V>{
    reference a;
};

就像这个例子

class myiterator: std::iterator<std::random_access_iterator_tag, int>{
    reference a;
};

但是我得到一个错误“‘reference’没有命名类型”。如何将 std::iterator<>::reference 与模板一起使用?

不会找到名称 reference,因为不会在依赖库 class std::iterator<std::random_access_iterator_tag, V> 中查找非依赖名称,这取决于模板参数 V .

您可以将 reference 作为从属名称:

template <class V>
class myiterator: std::iterator<std::random_access_iterator_tag, V>{
    typename std::iterator<std::random_access_iterator_tag, V>::reference a;
};

反之,非模板版本没有这个问题。

名称reference在基class中声明,基class是一个依赖类型(它的类型依赖于V)。有适用于这种情况的特殊规则:当编译器看到名称 reference 时,它不会搜索依赖基 class 作用域,因此不会找到该名称。为了强制编译器搜索依赖基 class 作用域,您必须限定名称。

您可能认为 iterator::reference 可以解决问题。不幸的是,这也不起作用。 iterator 作为 std::iterator<std::random_access_tag, V> 的 shorthand 本身在基 class 内部声明为它的“注入的 class 名称”。所以 iterator 也不会被找到,除非它被某些东西限定。

您可以输入很长的方式:typename std::iterator<std::random_access_tag, V>::reference a;。一种更具可读性的方式是:

using base = typename myiterator::iterator;
typename base::reference a;

您可以使用 base::myiterator class 定义的其余部分强制在基础 class 范围内进行查找。

在 C++20 中,typename 可以从这些上下文中省略。