使用range-v3视图实现begin()/ end()方法

时间:2018-02-23 09:49:10

标签: c++ range-v3

是否可以在类内部使用视图来实现begin()/ end()方法?

例如,我想使下面的类可迭代;在每次迭代 在两个迭代的当前元素上调用op

template <typename It1, typename It2, typename Op>
struct binary_op {
    binary_op(It1 const& f, It2 const& s, Op o): first{f}, second{s}, op{o} {}

    It1 first;
    It2 second;
    Op op;
};

感谢range-v3,我可以使用zip_with视图(未经过测试的代码!)

ranges::view::zip_with(op, first, second);

但是我可以使用这个视图实现begin()/ end()方法吗?

using namespace ranges;

template <typename It1, typename It2, typename Op>
struct binary_op {
    ...

    auto begin() const {
        return view::zip_with(op, first, second).begin();
    }

    auto end() const {
        return view::zip_with(op, first, second).end();
    }
};

可以安全地比较两个迭代器(开始和结束)吗?

我想要实现的最终结果是嵌套任意数量的binary_op:

std::vector<int> v1, v2, v3;

auto r = binary_op(
    binary_op(v1, v2, [](int a, int b) {return a + b;}),
    v3,
    [](int a, int b) {return a - b;});


for (auto x : r) { ... }

1 个答案:

答案 0 :(得分:0)

看起来这样做是安全的,但只是存储zip_with_view<...>而不是费心binary_op可能更容易。

请注意,您的示例不是合法的C ++,因为lambda表达式会产生一个对象,而不是一个类型。你需要

auto op1 = [](int, int) -> int {/*one thing*/};
auto op2 = [](int, int) -> int {/*other thing*/};
auto r = binary_op<
    binary_op<decltype(v1), decltype(v2), decltype(op1)>
    decltype(v3),
    decltype(op2)>{ { v1, v2, op1 }, v3, op2 };

此时你也可以

auto r = view::zip_with(op2,
                        view::zip_with(op1, v1, v2),
                        v3);