【问题标题】:Providing an iterator for the first element of a container of pairs为对容器的第一个元素提供迭代器
【发布时间】:2010-09-23 16:30:28
【问题描述】:

我有一个装满成对的容器。我想使用 STL 泛型算法对其进行迭代(在我的情况下,它将是 inner_product,但将其视为一个泛型问题)。 我使用的算法首先和最后需要迭代器。我可以提供特殊的迭代器 first 和 last 不会在对上而是在每对的第一个元素上进行迭代?

我知道我可以手动完成,提供一个手工制作的函数对象,它将是标准容器迭代器的包装器,将它尊重到该对本身的第一个成员意图,但我认为还有一个聪明的单线为我做这件事。会是什么?

【问题讨论】:

  • 你的意思是,例如你有一个 map.begin() ,你想迭代它的值(.second)?
  • 是的,这是同一基本问题的另一个实例。
  • 是的。允许升压。哎呀,它甚至是首选:-)

标签: c++ generics templates stl


【解决方案1】:

我环顾四周,找到了boost::transform_iterator。我想出了这段代码。令人惊讶的是它的效果如何:

#include <map>
#include <algorithm>
#include <iostream>
#include <string>
#include <iterator>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>

int main() {
    typedef std::map<std::string, int>::value_type value_type;
    std::map<std::string, int> a;
    a["one"] = 1;
    a["two"] = 2;

    // returns the second element 
    boost::function<int(value_type&)> f = boost::bind(&value_type::second, _1);
    std::copy(boost::make_transform_iterator(a.begin(), f), 
              boost::make_transform_iterator(a.end(), f),
              std::ostream_iterator<int>(std::cout, " "));

}

它将"1 2 " 打印到标准输出。

【讨论】:

  • 它与我认为我们将得到的“聪明的单班轮解决方案”一样接近...... :-)
  • 可以将所有内容放在一行中。但是您必须重复绑定调用。丑陋的代码复制'n'粘贴然后:)
【解决方案2】:

没有聪明的单线解决方案。您最大的希望是编写一个包装迭代器。这实际上是一个非常规范的解决方案。您可能会检查 Boost 是否已经拥有您需要的东西。如果没有,请尝试编写一个通用的包装器,可以重用于其他问题。

STL 包含一个称为reverse_iterator 的迭代器包装器。这个名字暗示了它的用途。

【讨论】:

    【解决方案3】:

    最终,我认为您的想法是可行的方法。您可以使用 Boost 来帮助您做到这一点。首先,您需要一个函数来获取您的配对并返回第一个元素。我认为您可以使用Lambda library 内联编写这样的函数,但为了便于阅读,我想我只需要编写一个简单的函数来代替。然后将该函数与您的原始迭代器一起传递,为您的序列的开始和结束构造一个transform_iterator

    【讨论】:

      【解决方案4】:

      你可以继承例如std::vector::const_iterator 自己,重新实现 operator* 和 operator-> 以返回对中的第一个。您还需要创建自己的 begin() 和 end() 函数来返回您的自定义迭代器。

      您还可以创建二进制函数类并将其传递给 inner_product。

      【讨论】:

      • 你确定我可以继承 stl 迭代器吗?我一直认为他们没有提供虚拟析构函数,也没有启用子类化。
      • 我没有说子类 std::iterator。我说的是子类 std::vector::const_iterator。我刚才试了一下,效果很好。
      • can (对不起,我的评论说“不能”,我的意思是“可以”)确实是 st​​d::iterator 的子类。它提供了所需的通用 typedef。它的目的不是提供多态接口
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-28
      • 2018-03-30
      相关资源
      最近更新 更多