按键擦除STL std :: set元素时编译错误

Ita*_*atz 1 c++ stl set visual-studio

我有以下代码,其中我将std :: set迭代器保存到ints 的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
Run Code Online (Sandbox Code Playgroud)

编译错误是:

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运算符 - 但我无法理解为什么或如何解决它.

Bjö*_*lex 5

问题是由list::iterator没有定义比较的事实引起的.a的值类型std::set需要严格的弱排序.

A vector支持随机访问迭代器,它具有排序.列表只需要支持双向迭代器,它没有排序(当然,实现也可以自由支持列表的随机访问迭代器,因此在某些编译器上它可能有效).

为了解决这个问题,你必须自己编写一个比较函数.问题是检测a中两个迭代器的顺序的唯一方法list是从一个遍历到另一个,这需要线性时间.