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.
首先,最简单的解决方案是迭代容器并从迭代器访问字段。
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)
正如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)
迭代器应该通过其操作(即读取、递增、递减、随机访问)进行接口,而不是通过其显式类型进行接口。迭代器按其支持的操作数量进行分类。
例如,如果您需要迭代一个范围并在一次传递中读取所有值,那么您需要输入迭代器作为参数。迭代器本身的类型应该是无关的。
你运气不好。
vector<int>::iterator不是多态的1 . 没有地方可以伸手更改指针步长。 vector<int>::iterator仅迭代一系列连续的 int对象,并且您的int对象不是连续存储的。
这就是为什么所有 C++ 标准算法都被模板化以接受任何类型的迭代器。如果您将函数设为接受任意迭代器类型的模板,则可以使用像 Snps 编写的迭代器适配器。
1多态性相对于指针运算来说很慢std::vector,如果它没有与普通数组类似的性能,没有人会使用它