C++ 如何在结构体向量的一个字段上创建迭代器

Bri*_*ian 6 c++ iteration struct vector

我有一个所有原始类型的结构,如下所示:

struct record {
    int field1;
    double field2;
}
Run Code Online (Sandbox Code Playgroud)

我有一个该结构实例的向量,如下所示:

vector<record> records;
Run Code Online (Sandbox Code Playgroud)

是否可能/创建vector<int>::iterator迭代的最佳方法是什么field1?如果我使用数组呢record records[n]?我需要看起来像的东西vector<int>::iterator

编辑:我需要的东西是vector<int>::iterator.

Snp*_*nps 5

制作迭代器适配器

首先,最简单的解决方案是迭代容器并从迭代器访问字段。

for (auto&& r : records) {
    int value = r.field1;
    /* do something with 'value' */
}
Run Code Online (Sandbox Code Playgroud)

无论如何,如果您确实想要一个field1在取消引用时返回的迭代器,您可以轻松实现从容器自己的迭代器派生的迭代器适配器。

struct my_it : public std::vector<record>::iterator {
    using std::vector<record>::iterator::iterator;
    int operator*() { return std::vector<record>::iterator::operator*().field1; }
};
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

for (my_it it = std::begin(records); it != std::end(records); ++it) {
    int value = *it; // Dereferencing now returns 'field1'.
}
Run Code Online (Sandbox Code Playgroud)

是XY问题吗?

正如Ben Voigt在答案中所解释的,除了存储在连续数组中的元素之外,没有办法创建一个std::vector<int>::iterator迭代其他内容的a 。int

如果您需要一个接受输入迭代器的函数,那么请将其设为模板函数。这样它就可以与任何容器类型的迭代器一起使用。标准库中的所有算法都是这样实现的。

template <typename InputIt>
void func(InputIt first, InputIt last) {
    for (; first != last; ++first) {
        value = *it; // Dereferences input iterator of any type.
    }
}
Run Code Online (Sandbox Code Playgroud)

迭代器应该通过其操作(即读取、递增、递减、随机访问)进行接口,而不是通过其显式类型进行接口。迭代器按其支持的操作数量进行分类。

例如,如果您需要迭代一个范围并在一次传递中读取所有值,那么您需要输入迭代器作为参数。迭代器本身的类型应该是无关的。

有关迭代器类别的更多信息,请参阅此内容


Ben*_*igt 3

你运气不好。

vector<int>::iterator不是多态的1 . 没有地方可以伸手更改指针步长。 vector<int>::iterator仅迭代一系列连续的 int对象,并且您的int对象不是连续存储的。

这就是为什么所有 C++ 标准算法都被模板化以接受任何类型的迭代器。如果您将函数设为接受任意迭代器类型的模板,则可以使用像 Snps 编写的迭代器适配器。


1多态性相对于指针运算来说很std::vector,如果它没有与普通数组类似的性能,没有人会使用它