【问题标题】:Test if two iterators come from same object测试两个迭代器是否来自同一个对象
【发布时间】:2013-07-03 18:00:24
【问题描述】:

给定两个相同类型的 std::iterators,如何测试它们是否来自同一个对象(不是类)?请注意,我不是在问如何比较它们的值。

std::string foo = "foo";
std::string bar = "bar";

std::string::iterator iter1 = foo.begin();
std::string::iterator iter2 = bar.begin();

if ( iter1 == iter2 )
{
    ...
}

以上应该并且确实失败了。如何在运行时检查这一点?查看源代码,我看到相关方法调用 iterator::_Compat() 这是一个 void 方法,它执行我想要的检查,但在失败时它会发出调试断言。它在发布版本中不会被注意到。

进一步看,我看到迭代器(至少对于字符串)有一个公共的_GetCont() 方法。所以

if ( iter1._GetCont() == iter2._GetCont() )

有效。但是,这是无证的,导致我相信使用它不安全。

我的问题是如何以便携的方式完成上述任务?

还要注意,这是迭代器模板类的一部分。我将无法控制第二个迭代器。

【问题讨论】:

  • 如您所料,_Compat_GetCont 函数完全依赖于实现,在其他实现中可能不存在(或命名不同)。在我的脑海中,我没有看到一种独立于平台的方式来检查这个(因为迭代器甚至根本不需要对容器的引用,而且在发布中很可能不会,即这个@ 987654327@ 甚至不应该在发布模式下工作)。不过,这是个好问题。

标签: c++ templates iterator


【解决方案1】:

我的问题是如何以便携的方式完成上述任务?

你不能。

一般来说,迭代器不需要知道(或让知道)它们指向的容器。迭代器是指针的泛化,它们所要做的就是表现得像指针。

因此它们可能允许取消引用、递增、递减、求和等,具体取决于它们的类别,但 C++ 标准中没有迭代器要求让用户知道它们指向哪个容器,或者它们是否指向与另一个迭代器相同的容器。

换句话说,迭代器范围的有效性应该是在该迭代器范围上工作的函数的前提条件。客户端有责任确保提供的迭代器指向同一个容器(并且第二个迭代器可以从第一个迭代器访问)。

例如,标准库是如何处理这个问题的(C++11 标准的第 24.2.1/7 段):

大多数在数​​据结构上运行的库算法模板都有使用范围的接口。 范围是一对指定计算开始和结束的迭代器。范围 [i,i) 是 空范围;通常,范围[i,j) 指的是数据结构中以元素开头的元素 i 指向的元素,直到但不包括 j 指向的元素。范围[i,j) 有效当且仅当 j 可从i 访问。 将库中的函数应用于无效范围的结果未定义

【讨论】:

  • 我明白了。这是我的困境:我编写了一个模板类来处理 utf 编码方案之间的转换。它基本上是标准 std::string::iterators 的包装器。除了动态转换代码点外,它的行为必须与底层迭代器完全相同。实现不等式关系运算符时出现了问题。如果两个迭代器不相关,我希望抛出异常,但现在我发现即使是 STL 也不会这样做。
  • @Waldermort:确实,只依赖未定义的行为;)
【解决方案2】:

你可能想要比较指针

if ( &(*iter1) == &(*iter2) )
{
    ...
}

【讨论】:

  • 只测试它们是否指向同一个内存,而不是它们是否来自同一个对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-29
  • 2012-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多