0

以下是我的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() ) ; }

ICP:

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])用作模板参数,除非该组件特别允许。

以及对此的历史讨论

4

2 回答 2

1

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

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

接下来是std::iterator_traits< iterator_base >::pointer嵌套类中的使用。这一次,iterator_traits<iterator_base>已经被实例化了,所以什么都没做,::pointer而是被搜索了。但由于尚未声明,因此无法找到。

请注意,当您注释掉该using行时,代码中的任何内容都不会再实例化嵌套的类主体(类模板的成员主体是“延迟实例化”),因此这不能衡量或反对该嵌套类体内的构造。

于 2016-10-28T20:18:56.120 回答
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.

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

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

于 2016-10-28T20:08:15.747 回答