结构 std::iterator_traits<...> 中没有名为“指针”的类型

no type named ‘pointer’ in struct std::iterator_traits<...>

这是我的 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 ;
}

当我不注释 using... 行时,代码无法编译。

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() ) ; }

国际文联:

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() ) ; }

没有那一行,所有编译都很好。

问题是:当我在上面的代码中评论 using difference_type = typename std::iterator_traits< iterator >::difference_type; 时会发生什么(只有这样的更改才能编译代码)。?

============================================= ============================= res.on.functions/2.5

  1. In particular, the effects are undefined in the following cases:...
    1. if an incomplete type ([basic.types]) is used as a template argument when instantiating a template component, unless specifically allowed for that component.

和历史 discussion

#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
{}

Pointer_nah 的声明点,类型 Nah 是一个不完整的类型。

iterator_traits 必须查看该类型的内部才能找到它的 pointer 定义。

但是,递归地,需要定义 iterator_traits<Nah>

以此类推

但是,要点:Nah 在声明 Pointer_nah 的地方是不完整的。 Incomplete 表示 class 不完全已知。特别是这里不知道它的大小,所以不能传递给 sizeof.

我怀疑这就是您的一位编译器惊呼的原因,

error: incomplete type is not allowed

此处的错误是 std::iterator_traits< iterator_base > 类型仍然不完整,并且在您要访问 ::pointer 时尚未提供 pointer 成员。

class std::iterator_traits<iterator_base> 正在被 typename std::iterator_traits< iterator_base >::difference_type 实例化,因为它被用在 :: 的左侧,并且因为它还没有被实例化。这会触发 linked_list<int>::iterator_base 的实例化,因为 iterator_traits 的主体使用 class 来定义其各种成员类型定义 - 例如,实例化可能发生在看起来像 typedef typename Iterator::value_type value_type; 的行在标准库中。

下面是std::iterator_traits< iterator_base >::pointer在你的嵌套class中的使用。这次,iterator_traits<iterator_base>已经被实例化了,所以什么都不做,搜索::pointer。但由于尚未宣布,因此无法找到。

请注意,当您注释掉 using 行时,代码中的任何内容都不会再实例化嵌套的 class 主体(class 模板成员的主体是 "lazily instantiated"),因此这不能作为支持或反对嵌套 class 主体内部结构有效性的衡量标准。