如何通过引用迭代器的解引用使幂等性

How to make idempotent taking a reference to a dereference of an iterator

本文关键字:引用 何通过 迭代器      更新时间:2023-10-16

下面的代码(-std=c++11)根据"天真"视图应该可以工作。相反,它没有(应该知道并理解为什么没有)。修改代码(重载&)以使其按照"天真"的观点行事的最短方法是什么?在stl对象创建过程中,这不应该作为一个选项吗(不需要写太多)?

#include <iostream>
#include <vector>
int main(int argc, char **argv)
{   std::vector<int> A{10,20,30};
    auto i=A.begin();
    auto j=&*i;
    std::cout<<"i==j gives "<<(i==j)<<std::endl;
    return 0;
}

问题无法解决。有三个原因无法解决。

第一个问题

需要重载的operator &是向量元素类型的operator &。您不能为任意类型重载operator &,特别是不能为内置类型重载它(如示例中的int)。

第二个问题

假设您希望这适用于std::vectorstd::array和内置阵列?也可能是std::liststd::deque等?你不能。每个包含的迭代器都是不同的(在实践中:在理论中,它们中的一些可以共享迭代器,但我不知道它们有任何标准库。)

第三个问题

如果您准备接受这只适用于std::vector<MyType>,那么您可以重载MyType::operator &,但仍然无法计算出MyType对象所在的std::vector<MyType>(您需要它来获得迭代器)。

首先,在您的代码片段中,i推导为std::vector<int>::iteratorj推导为int*。编译器不知道如何将std::vector<int>::iteratorint*进行比较。

为了实现这一点,您可以提供一个重载的operator==,它将以以下方式将向量迭代器与向量值类型指针进行比较:

template<typename T>
bool operator==(typename std::vector<T>::iterator it, T *i) {
  return &(*it) == i;
}
template<typename T>
bool operator==(T *i, typename std::vector<T>::iterator it) {
  return it == i;
}

实时演示

这不应该起作用,甚至"符合‘天真’视图"也不应该。尽管每个指针都是迭代器,但反过来不一定是真的。你为什么希望它起作用?

它将在两种情况下工作:

  1. std::vector<T>实现的iterator实际上是T*。那么您的代码将从decltype(i) == int*decltype(j) == int*)开始工作。某些编译器可能会出现这种情况,但如果编译器确实存在这种情况,您甚至不应该依赖它。

  2. 解引用运算符不返回类型为T的对象,而是返回可转换为T的对象,并且具有重载的operator&,从而返回迭代器。事实并非如此,原因很充分。

正如其他人所建议的那样,您可以重载operator==来检查两个间接方法(指针和迭代器)是否引用了同一个对象,但我怀疑您希望运算符的地址返回迭代器,如果迭代器不是指针,则无法实现,因为存储在向量中的对象类型没有向量/迭代器或其他概念。

问题不在等式运算符中,我需要的是定义解引用运算符来给出迭代器

你不能。有问题的解引用运算符是std::vector<int>::iterator,它是标准库的一部分,您可以(也不应该)操作它


注意,由于std::vector<T, A>中的C++11,

  • CCD_ 31是CCD_
  • 33是CCD_ 34

此外,以下情况也是正确的:

  • 所有输入迭代器i都支持*i,它提供类型为T的值,CCD_37是该迭代器的值类型
  • std::vector<T>的迭代器需要将T作为其值类型
  • std::vector<T>的迭代器是输入迭代器