MSVC 2015 - 自定义迭代器的std :: for_each中的编译器错误(仅在DEBUG中时)

时间:2016-03-16 10:11:39

标签: c++ stl visual-studio-2015

我已经实现了一个自定义容器类及其迭代器,并尝试在其上使用for_each。在VC6,在线cpp.sh和MSVC15中,一切都很好,后者仅在发布时:当在调试中我遇到一系列错误时,我报告了我的代码的过度简化版本。

struct Functor {
  void operator()(int&) {}
} func;

struct Container {
  typedef int value_type;
  struct iterator {
    bool operator!=(iterator const&) { return true; }
    iterator& operator++() { return *this; }
    value_type& operator*() { return i; } //this is just to compile, not for real
    int i; //this is just to compile, not for real
  };
  iterator begin() { return iterator(); }
  iterator end() { return iterator(); }
};

#include <algorithm>
int main() {
  Container c;
  std::for_each(c.begin(), c.end(), func);  // compile errors
  return 0;
}

错误:

1>c:\program files\microsoft visual studio 14.0\vc\include\xutility(838): error C2672: '_Iter_cat': no matching overloaded function found
1>  c:\program files\microsoft visual studio 14.0\vc\include\algorithm(31): note: see reference to function template instantiation 'void std::_Debug_range_ptr<_InIt,_Fn1>(_InIt,_InIt,_Pty &,std::_Dbfile_t,std::_Dbline_t)' being compiled
1>          with
1>          [
1>              _InIt=Container::iterator,
1>              _Fn1=Functor,
1>              _Pty=Functor
1>          ]
1>  [...]: note: see reference to function template instantiation '_Fn1 std::for_each<Container::iterator,Functor>(_InIt,_InIt,_Fn1)' being compiled
1>          with
1>          [
1>              _Fn1=Functor,
1>              _InIt=Container::iterator
1>          ]
1>c:\program files\microsoft visual studio 14.0\vc\include\xutility(838): error C2893: Failed to specialize function template 'iterator_traits<_Iter>::iterator_category std::_Iter_cat(const _Iter &)'
1>  c:\program files\microsoft visual studio 14.0\vc\include\xutility(838): note: With the following template arguments:
1>  c:\program files\microsoft visual studio 14.0\vc\include\xutility(838): note: '_Iter=Container::iterator'
1>c:\program files\microsoft visual studio 14.0\vc\include\xutility(838): error C2672: '_Debug_range_ptr2': no matching overloaded function found
1>c:\program files\microsoft visual studio 14.0\vc\include\xutility(838): error C2780: 'void std::_Debug_range_ptr2(_RanIt,_RanIt,_Pty &,std::_Dbfile_t,std::_Dbline_t,std::random_access_iterator_tag)': expects 6 arguments - 5 provided
1>  c:\program files\microsoft visual studio 14.0\vc\include\xutility(820): note: see declaration of 'std::_Debug_range_ptr2'
1>c:\program files\microsoft visual studio 14.0\vc\include\xutility(838): error C2780: 'void std::_Debug_range_ptr2(_InIt,_InIt,_Pty &,std::_Dbfile_t,std::_Dbline_t,std::input_iterator_tag)': expects 6 arguments - 5 provided
1>  c:\program files\microsoft visual studio 14.0\vc\include\xutility(811): note: see declaration of 'std::_Debug_range_ptr2'

2 个答案:

答案 0 :(得分:1)

使用迭代器时,MSVC具有更广泛的调试检查。据推测,这需要对迭代器及其所有嵌入类型进行更完整的定义。

传统的迭代器派生自std::iterator<>,它为所需的嵌入类型提供默认定义。

template< 
    class Category,
    class T,
    class Distance = std::ptrdiff_t,
    class Pointer = T*,
    class Reference = T& 
> struct iterator;

对代码进行如下更改应该可以解决问题;

  struct iterator : std::iterator<
    std::input_iterator_tag, // or as required
    int
  >

答案 1 :(得分:0)

通常,迭代器被定义为标准类std::iterator的派生类,它被声明为

template<class Category, class T, class Distance = ptrdiff_t,
class Pointer = T*, class Reference = T&> struct iterator;

其模板参数之一是Category,用于确定迭代器的类别标记,例如std::input_iterator_tag

在调试模式下,编译器根据迭代器的类别执行一些检查。

您应该遵循这个定义迭代器的标准模型。