【问题标题】:How to create iterator for member element from the iterator of std container?如何从 std 容器的迭代器中为成员元素创建迭代器?
【发布时间】:2019-06-06 20:16:55
【问题描述】:

我只需要为成员元素创建一个迭代器来遍历容器。

例如:

class A { int x; char y; };

std::vector<A> mycoll = {{10,'a'}, {20,'b'}, {30,'c'} };

这里mycoll.begin()会给我A类型的迭代器

但我需要编写迭代器来迭代特定成员(比如 x A.x)并让 int_ite 成为该整数的迭代器。

那我需要

*(int_ite.begin() ) 返回 10

*(++int_ite.begin() ) 返回 20

等等

.end() 也会结束迭代。

有没有什么优雅的方法可以创建这样一个迭代器? 我要求它传递给std::lower_bound()

【问题讨论】:

  • 你不能使用int_ite.begin()-&gt;x
  • 您在创建迭代器时究竟发现了什么问题?你试过写迭代器了吗?
  • 确定可以实现类似迭代器的东西,只返回字段 x,但如此奇怪和复杂
  • 对于std::lower_bound,您也不需要它,自定义比较器可以完成这项工作。
  • 旁注:如果您发现自己确实需要这样做,Mooing Duck has an excellent piece 了解如何开始制作容器及其迭代器。

标签: c++ c++11 iterator


【解决方案1】:

使用range-v3,您可以创建视图:

std::vector<A> mycoll = {{10,'a'}, {20,'b'}, {30,'c'} };

for (auto e : mycoll | ranges::view::transform(&A::x)) {
    std::cout << e << " "; // 10 20 30
}

对于lower_bound,range-v3 有投影:

auto it = ranges::v3::lower_bound(mycoll, value, std::less<>{}, &A::x);
// return iterator of mycoll directly :-)

如果是 std,你可以使用自定义比较器和 std::lower_bound

auto it = std::lower_bound(mycoll.begin(), mycoll.end(),
                           value,
                           [](const A& a, int x){ return a.x < x; });

【讨论】:

  • 感谢您的代码。问题的解决方案并不那么明显。
【解决方案2】:

来自cppreference(重载(2)):

template< class ForwardIt, class T, class Compare >
ForwardIt lower_bound( ForwardIt first, ForwardIt last, const T& value, Compare comp );

要找到成员 x 的下限,您可以将比较该成员的比较器作为最后一个参数传递。

您通常将函子传递给指定如何处理或评估容器元素的算法,而不必编写复杂的迭代器。标准库对编写自己花哨的迭代器的支持相当差,而算法却相当强大。

【讨论】:

    猜你喜欢
    • 2014-02-02
    • 1970-01-01
    • 2011-03-24
    • 1970-01-01
    • 2018-05-20
    • 2021-08-17
    • 1970-01-01
    • 2013-11-08
    • 2016-07-24
    相关资源
    最近更新 更多