简体   繁体   English

如何在容器项的字段上创建迭代器?

[英]How can I make an iterator over fields of container's items?

So, say, I have a class that has std::list<std::pair<int, std::string>> inside of it; 所以,比方说,我有一个在其中有std::list<std::pair<int, std::string>>的类; how can I implement an iterator for this class such that it iterates over strings contained in this list? 如何为此类实现迭代器,以便迭代此列表中包含的字符串?

Or, for example, in my class I have a vector of struct s with fields a , b and c ; 或者,例如,在我的班级中,我有一个带有字段abcstruct的向量; can I create an iterator (maybe inherit vector's iterator? don't know), which, when dereferenced, will return a std::pair , corresponding to (b, c) ? 我可以创建一个迭代器(也许继承向量的迭代器吗?不知道),当取消引用时,它将返回一个std::pair ,对应于(b, c)

By iterator I mean something like std::vector 's iterators: something, that I can get via whatever.begin() and iterate over, as mentioned, strings inside the list. 通过迭代器,我的意思是像std::vector的迭代器:我可以通过whatever.begin()得到的whatever.begin() ,如上所述,迭代遍历列表中的字符串。

UPD Okay, here's more info on what I want. UPD好的,这里有关于我想要的更多信息。 In my HashMap class I have items : a list of structs : each with a key, a value and a pointer to it's place in the table. 在我的HashMap类中,我有一些items :一个structs列表:每个structs都有一个键,一个值和一个指向它在表中的位置的指针。 What I need is an iterator; 我需要的是一个迭代器; but not the one that I can get by doing items.begin() , since this iterator, when dereferenced, will return my struct. 但不是我可以通过执行items.begin()获得的items.begin() ,因为这个迭代器在取消引用时会返回我的结构。 I need an iterator, such that I can return it when user calls HashMap.begin() , and it should dereference into a std::pair , corresponding to (key, value). 我需要一个迭代器,这样我可以在用户调用HashMap.begin()时返回它,它应该取消引用到std::pair ,对应于(key,value)。

This should, hopefully, make my question clearer. 希望这应该让我的问题更清楚。

UPD2 Here is my struct , if that helps: UPD2这是我的struct ,如果有帮助:

template<class KeyType, class ValueType>
struct node {
    KeyType key;
    ValueType value;
    node** place;

    node(KeyType key_ = KeyType(), ValueType value_ = ValueType()): key(key_), value(value_) {};
};

One elegant way is to use transforming iterators or a transformed range: 一种优雅的方法是使用转换迭代器或转换范围:

#include <iostream>
#include <list>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/iterator/transform_iterator.hpp>

int main() {
    std::list<std::pair<int, std::string>> l;
    auto extractor = [](auto&& elem) { return elem.second; };

    // Using a transformed range.
    for(auto&& v: l | boost::adaptors::transformed(extractor))
        std::cout << v << '\n';

    // Using transform iterators.
    for(auto i = boost::make_transform_iterator(l.begin(), extractor), j = boost::make_transform_iterator(l.end(), extractor); i != j; ++i)
        std::cout << *i << '\n';
}

To use a transform iterator for you containers you can do something like: 要为容器使用转换迭代器,您可以执行以下操作:

struct MyContianer
{
    std::list<std::pair<int, std::string>> container;

    static auto constexpr first_extractor = [](auto&& elem) { return elem.second; };
    using iterator_first = decltype(boost::make_transform_iterator(container.begin(), first_extractor));
    iterator_first begin_first() { return {container.begin(), first_extractor}; }
    iterator_first end_first() { return {container.end(), first_extractor}; }

    static auto constexpr second_extractor = [](auto&& elem) { return elem.second; };
    using iterator_second = decltype(boost::make_transform_iterator(container.begin(), second_extractor));
    iterator_second begin_second() { return {container.begin(), second_extractor}; }
    iterator_second end_second() { return {container.end(), second_extractor}; }

};
decltype(MyContianer::first_extractor) constexpr MyContianer::first_extractor;
decltype(MyContianer::second_extractor) constexpr MyContianer::second_extractor;

int main() {
    MyContianer c;
    c.begin_first();
    c.begin_second();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用包含策略类型的容器创建容器迭代器? - How can I create a container iterator with the container holding a policy type? 类/结构容器上的迭代器,在取消引用时访问其成员字段 - Iterator over a container of classes/structs that accesses their member fields on being derefenced 基于 items 属性的容器上的 C++ 自定义迭代器 - C++ custom iterator over container based on items property 如何在多个排序列表上创建迭代器? - How to make an iterator over several sorted lists? 如何制作一个指向列表迭代器的指针,以将其作为参数传递给函数? - How can I make a pointer to list iterator to pass into function as an argument? 如何使我的迭代器类看起来不像容器类? - How do I make my iterator classes not look like container classes? 容器的迭代器能否产生左值以外的东西? - Can a container's iterator yield something other than an lvalue? 如何使用迭代器设计模式为 C++ 中的包装容器类提供多个迭代器? - How can I use the Iterator design pattern to provide multiple iterators for a wrapper container class in C++? 如何将BOOST_FOREACH与仅支持const_iterator的容器一起使用? - How can I use BOOST_FOREACH with a container supporting only const_iterator? 如何使迭代器 class 成为容器的成员 class c++ - how to make an iterator class a member of a container class c++
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM