首页 文章

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

提问于
浏览
1

我有以下代码,其中我将一组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 回答

  • 5

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

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

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

相关问题