我已经实现了一个自定义容器类及其迭代器,并尝试在其上使用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'
答案 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
。
在调试模式下,编译器根据迭代器的类别执行一些检查。
您应该遵循这个定义迭代器的标准模型。