迭代时调用成员函数时,迭代时

Iterator adaptor that calls a member function when dereferenced

本文关键字:迭代 函数 调用 成员      更新时间:2023-10-16

我正在尝试编写一个迭代器适配器,该适配器应在每次被授予时都应调用成员函数(或访问对象的成员)。这是这样的API的示例:

vector<pair<int,int>> ps = {{1,"a"}, {2,"b"}, {3,"c"}};
// Pairs that represent ranges
auto rf = make_adaptor(ps.begin(), ps.end(), [](const auto& x) {return x.first;}
auto rs = make_adaptor(ps.begin(), ps.end(), [](auto& x) {return x.second;}

应该打印出123

for_each(rf.first, rf.second, [](const auto& x){std::cout << x;});

应该在ps中设置对的每个second元素:

for_each(rs.first, rs.second, [](auto& x){ x = "hello";});

我尝试使用make_adaptor方法一起编写自己的iterator类型,但我似乎无法正常工作:

template <typename Iterator, typename UnaryOp>
struct adaptor {
    using value_type = std::result_of<UnaryOp(typename Iterator::reference)>::type;
    using reference = value_type&;
    using pointer = value_type*;
    using difference_type = typename Iterator::difference_type;
    using iterator_category = typename Iterator::iterator_category;
    adaptor(){};
    adaptor(Iterator it, UnaryOp func) : _it(it), _func(func) {}
    reference operator*() const { return _func(*_it); }
    pointer operator->() const { return &_func(*_it); }
    bool operator==(const adaptor& other) const { return _it == other._it; }
    bool operator!=(const adaptor& other) const { return _it != other._it; }
    adaptor& operator++() {
        ++_it;
        return *this;
    }
    Iterator _it;
    UnaryOp _func;
};

template <typename Iterator, typename UnaryOp>
    auto make_adaptor(Iterator first, Iterator last, UnaryOp func) {
        return std::make_pair(adaptor<Iterator, UnaryOp>(first, func),
                              adaptor<Iterator, UnaryOp>(last, func));
    };

的原因是:假设我有一个在points上使用的算法convex_hull。但是现在我有包含points作为成员的对象(struct A { points pos;};)。我想在As。

的集合上致电convex_hull

使用range-v3,您可以做类似的事情:

const std::vector<std::pair<int,const char*>> ps = {{1,"a"}, {2,"b"}, {3,"c"}};
for (const auto s : ps | ranges::view::keys)
{
    std::cout << " " << s;
}
for (const auto s : ps | ranges::view::transform([](const auto& p) { return p.first;} ))
{
    std::cout << " " << s;
}

demo