伪造插入器是一种好习惯吗?

Gri*_*ngo 16 c++ algorithm stl

我们被教导创建函数对象以使用算法.

有算法可以调用operator(),如:

  • 的for_each
  • find_if
  • 的remove_if
  • max_element
  • count_if

这些函数对象通常应该从函数,谓词等继承unary_function或binary_function表现.

但书籍通常不会展示创建的示例OutputIterators:

例如,要遍历函数的输出 std::set_intersection(),我必须提供目标容器,然后遍历结果:

std::vector<int> tmp_dest;

std::set_difference (
        src1.begin(), src1.end(), 
        src2.begin(), src2.end(), 
        std::back_inserter(tmp_dest));

std::for_each( tmp_dest.begin(), tmp_dest.end(), do_something );
int res = std::accumulate( tmp_dest.begin(), tmp_dest.end(), 0 );
Run Code Online (Sandbox Code Playgroud)

但是认为有时使用每个算法的值而不先存储它们会更有效,例如:

std::set_difference (
        src1.begin(), src1.end(), 
        src2.begin(), src2.end(), 
        do_something );

Accumulator accumulate(0);  // inherits from std::insert_iterator ?
std::set_difference (
        src1.begin(), src1.end(), 
        src2.begin(), src2.end(), 
        accumulate );
Run Code Online (Sandbox Code Playgroud)
  • 我们通常应该创建像这个累积器的类吗?
  • 它的设计应该是什么样的?
  • 它应该继承什么? 累加器可以继承insert_iterator,但它实际上不是迭代器(例如它没有实现operator++())

什么是广泛接受的做法?

Seb*_*edl 6

如果你想要一个输出迭代器来为你收到的每个值调用你自己的函数,请使用Boost.Iterator的function_output_iterator.

  • +1如果你不介意,我发布了一个演示 (2认同)

Jar*_*d42 1

以下作品:

#include <cassert>
#include <algorithm>

class AccumulatorIterator
{
public:
    explicit AccumulatorIterator(int initial) : value(initial) {}

    AccumulatorIterator& operator = (int rhs) { value += rhs; return *this; }
    AccumulatorIterator& operator *() { return *this; }

    AccumulatorIterator& operator ++() { return *this; }
    operator int() const { return value; }
private:
    int value;
};

int main() {
    int first[] = {5,10,15,20,25};
    int second[] = {50,40,30,20,10};

    std::sort(std::begin(first), std::end(first));   //  5 10 15 20 25
    std::sort(std::begin(second), std::end(second)); // 10 20 30 40 50

    const int res = std::set_intersection (std::begin(first), std::end(first),
        std::begin(second), std::end(second), AccumulatorIterator(0));

    assert(res == 10 + 20);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)