【问题标题】:Flexible mutation of sequence containers in C++C++中序列容器的灵活变异
【发布时间】:2011-03-06 02:19:27
【问题描述】:

我正在考虑 STL 迭代器的当前限制,并想知道是否有一种优雅的方法来解决它。这是我的情况:我有一个类,它封装了一个序列容器和一个通用方法来改变容器的内容,例如:

class Container {
  typedef std::vector<int> Data;
  Data data_;
 public:
  template <class Mutator>
  ?? mutate() {
    Mutator m;
    return m(??);
  }
};

为了简洁,省略了一些细节,但我正在考虑的主要问题是将什么传递给 mutator(m() 函子调用中的 ??)。第二个问题是从 mutate 返回什么以允许对 mutators 进行简单组合。 一种可能性是将一对开始/结束迭代器传递(并返回)到 data_,甚至是 boost::sub_range,例如:

template <class Mutator>
boost::sub_range<Data> mutate() {
  Mutator m;
  return m(boost::sub_range<Data>(data_);
}

这将允许我对数据执行大部分我想要的操作,例如否定范围内的所有值、乘以一个因子等。这也允许我链接或组合各种变异器,如下所示(缩短) 版本:

return m1(m2(m3(data_)));

因此,例如,任何 mutator 都可以选择其输入的一个子范围来限制外部 mutator 工作的范围,这是一个理想的功能。而且所有这些 mutator 都可以就地更改数据,这非常有效。

然而,这种语法不能做的是修改容器的大小(至少不能使用向量),因此插入或删除元素的 mutator 不能与基于迭代器的接口一起使用。另一个接口将整个容器传递给 mutator。我不知道在这种情况下如何处理子范围,而且感觉它不像通用的和最低要求的基于迭代器的解决方案那样优雅。

如果有任何关于如何处理此限制的想法,我将不胜感激。

【问题讨论】:

    标签: c++ stl iterator containers mutable


    【解决方案1】:

    您可以将仿函数(思考:函数组合)与boost::bind 结合起来。

    另一方面,我觉得我不完全理解:第二个仿函数是否应该在与第一个仿函数不同的范围内工作?数据会从容器中删除吗?

    请注意:您当前的解决方案具有不明显的成本:“mutators”的每个组合都需要新的迭代,而不是“mutators 的真正组合”。

    【讨论】:

    • 我的示例组合应该支持一般突变仅限于输入子范围的情况。例如,一个“mutator”可以接受一个排序的整数序列并只返回非负子序列,而第二个mutator然后取这个子范围内所有元素的平方根。至于多次迭代的效率,我不太担心——mutators 旨在利用随机访问容器/迭代器。
    • @Eitan 在这种情况下,“Mutator”完全是用词不当。无论如何,您都没有改变输入,您正在选择它的一部分,实际上您将迭代和要对元素执行的操作一起抛出。也许迭代器适配器更符合您的需求。
    • 是的,你对非变异变异器的错误命名是正确的,变异子范围的优雅方法是使用迭代器适配器。但主要问题仍然是,当容器的大小也可能受到影响时,最优雅的变异接口是什么。
    猜你喜欢
    • 2015-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-29
    • 2011-10-08
    • 1970-01-01
    • 1970-01-01
    • 2015-02-24
    相关资源
    最近更新 更多