为什么我不能对模板使用 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
可以从这些上下文中省略。
我试过这样做
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
可以从这些上下文中省略。