我有以下代码,其中我将一组std :: it迭代器保存到 int
的STL容器中,并按键擦除元素(其中键是STL容器的迭代器) . 如果容器是std :: vector,代码将按预期编译并运行(编译器是VC 2008),但如果容器是std :: list则无法编译
using namespace std;
typedef vector< int > Container; //--> fails to compile if 'vector' is changed to 'list'
typedef Container::iterator IntIt;
set< IntIt > itSet;
Container c;
c.push_back (1);
c.push_back (2);
c.push_back (3);
IntIt it = c.begin ();
itSet.insert (it++);
itSet.insert (it++);
itSet.erase (c.begin ()); //--> The problematic line
编译错误是:
c:\ Program Files(x86)\ Microsoft Visual Studio 9.0 \ VC \ include \ functional(143):错误C2784:'bool std :: operator <(const std :: _ Tree <_Traits>&,const std :: _ Tree <_Traits>&)':无法从'const IntIt'推断'const std :: _ Tree <_Traits>&'的模板参数
因此在我看来错误是因为编译器将模板的一个 <
解释为 smaller than
运算符 - 但我无法理解为什么或如何解决它 .
1 回答
问题是由
list::iterator
没有定义比较的事实引起的 .std::set
的值类型需要严格的弱排序 .vector
支持随机访问迭代器,它具有排序 . 列表只需要支持双向迭代器,它没有排序(当然,实现也可以自由支持列表的随机访问迭代器,因此在一些编译器上它可能有效) .为了解决这个问题,你必须自己编写一个比较函数 . 问题是检测
list
中两个迭代器的顺序的唯一方法是从一个走到另一个,这需要线性时间 .