struct std :: iterator_traits< ...>中没有名为'pointer'的类型

时间:2016-10-28 18:31:56

标签: c++ c++11 templates 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() ) ; }

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

没有那条线,所有编译都很好。

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

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

  
      
  1. 特别是,在以下情况下 效果未定义 :...      
        
    1. 如果在实例化模板组件时将不完整类型([basic.types])用作模板参数,除非特别指出   允许该组件。
    2.   
  2.   

和历史discussion

2 个答案:

答案 0 :(得分:1)

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

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

以下是在嵌套类中使用std::iterator_traits< iterator_base >::pointer。这次,iterator_traits<iterator_base>已经被实例化,因此没有做任何事情,并且搜索了::pointer。但由于尚未宣布,因此无法找到。

请注意,当您注释掉using行时,代码中的任何内容都不再实例化嵌套类主体(类模板成员的主体是“懒惰地实例化”),所以这不可能是衡量或反对嵌套类体内部构造的有效性的措施。

答案 1 :(得分:0)

#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时不完整。 不完整表示该类未完全知晓。特别是它的大小在这里是未知的,所以它不能传递给sizeof

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

  

错误:不允许不完整的类型