[英]no type named ‘pointer’ in struct std::iterator_traits<…>
Here are the fragments of my linked_list template : 这是我的linked_list模板的片段:
#include <iostream>
#include <iterator>
template < class >
struct linked_list {
struct iterator_base : public std::iterator< std::bidirectional_iterator_tag , int >
{
typename std::iterator_traits< iterator_base >::pointer operator -> () const {
std::cerr << __func__ ;
return nullptr ; } ;
};
using difference_type = typename std::iterator_traits< iterator_base >::difference_type ;
} ;
int main ()
{
int * inullptr = linked_list< int >::iterator_base().operator->() ;
return 0 ;
}
When I leave using...
line uncommented, the code doesn't compile. 当我不
using...
行注释时,代码不会编译。
g++5.4 : g ++ 5.4:
list2.cxx:105:66: error: no type named ‘pointer’ in ‘struct std::iterator_traits<linked_list<int>::iterator_base<(linked_list<int, std::allocator<int> >::constantness)1u> >’
typename std::iterator_traits< iterator_base >::pointer operator -> () const { return &( to_obj_node( current_node_ ) -> object() ) ; }
icpc : icpc:
list.cxx(105): error: incomplete type is not allowed typename std::iterator_traits< iterator_base >::pointer operator -> () const { return &( to_obj_node( current_node_ ) -> object() ) ; }
Without that line all compiles fine. 没有那条线,所有编译都可以。
the question is : What happens, when i'm commenting using difference_type = typename std::iterator_traits< iterator >::difference_type;
问题是:当我
using difference_type = typename std::iterator_traits< iterator >::difference_type;
注释时,会发生什么? in above code ( only with such changes code compiles ).? 在上面的代码中(仅在进行此类更改时才编译)。
========================================================================== res.on.functions/2.5 ================================================== ========================功能/2.5
- In particular, the effects are undefined in the following cases:...
特别是在以下情况下效果不确定 :...
- if an incomplete type ([basic.types]) is used as a template argument when instantiating a template component, unless specifically allowed for that component.
如果在实例化模板组件时将不完整的类型([basic.types])用作模板参数,除非该组件特别允许。
and historical discussion on that. 以及对此的历史讨论 。
The error here is that the type std::iterator_traits< iterator_base >
is still incomplete and at the time that you want to access ::pointer
does not yet provide that pointer
member. 这里的错误是
std::iterator_traits< iterator_base >
类型仍然不完整,并且在您要访问::pointer
尚未提供该pointer
成员。
The class std::iterator_traits<iterator_base>
is being instantiated by typename std::iterator_traits< iterator_base >::difference_type
, because it's used on the left side of a ::
, and because it has not yet been instantiated. 类
std::iterator_traits<iterator_base>
由typename std::iterator_traits< iterator_base >::difference_type
实例化,因为它在::
的左侧使用,并且尚未实例化。 This triggers the instantiation of linked_list<int>::iterator_base
because the body of iterator_traits
uses that class to define its various member typedefs - for example the instantiation could happen at a line that looks like typedef typename Iterator::value_type value_type;
这触发的实例化
linked_list<int>::iterator_base
因为身体iterator_traits
使用该类来定义它的各种构件的typedef -例如实例化可以在一行,看起来像发生typedef typename Iterator::value_type value_type;
in the Standard library. 在标准库中。
What follows is the use of std::iterator_traits< iterator_base >::pointer
in your nested class. 接下来是在嵌套类中使用
std::iterator_traits< iterator_base >::pointer
。 This time, iterator_traits<iterator_base>
is already being instantiated, so nothing is done, and ::pointer
is searched. 这一次,
iterator_traits<iterator_base>
已经被实例化,所以什么也没做,并且搜索::pointer
。 But since that wasn't declared yet, it can't found. 但是由于尚未声明,因此无法找到。
Note that when you comment-out the using
line, nothing in the code will instantiate the nested class body anymore (the body of members of class templates are "lazily instantiated"), so this can't be a measure for or against the validity of the constructs inside of that nested class body. 请注意,当注释掉
using
行时,代码中的任何内容都不会再实例化嵌套的类主体(类模板的成员主体被“延迟实例化”),因此,这不能作为衡量有效性的标准。嵌套类主体内部的结构。
#include <iterator>
struct OK_1: std::iterator<std::bidirectional_iterator_tag, int> {};
using Pointer_1 = typename std::iterator_traits<OK_1>::pointer;
struct Nah
{
using Pointer_nah = typename std::iterator_traits<Nah>::pointer; //!
};
auto main() -> int
{}
At the point of declaration of Pointer_nah
, the type Nah
is an incomplete type. 在
Pointer_nah
的声明点,类型Nah
是不完整的类型。
iterator_traits
has to look inside that type in order to find its pointer
definition. iterator_traits
必须查看该类型的内部才能找到其pointer
定义。
But that, recursively, requires the definition of iterator_traits<Nah>
. 但这需要递归地定义
iterator_traits<Nah>
。
And so on. 等等。
But, main point: Nah
is incomplete at the point where Pointer_nah
is declared. 但是,要点是:在宣告
Pointer_nah
那一刻, Nah
是不完整的。 Incomplete means that the class is not fully known. 不完整意味着该类不是完全已知的。 In particular its size is not known here, so it can't be passed to
sizeof
. 特别是此处的大小未知,因此无法将其传递给
sizeof
。
I suspect that that's the reason why one of your compilers exclaimed, 我怀疑这就是您的一位编译器大喊大叫的原因,
” error: incomplete type is not allowed
”错误:类型不完整
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.