0

Is it possible to use a view internally to a class in order to implement the begin() / end() methods?

For example I want to make the following class iterable; at every iteration op is called on the current element of the two iterables.

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;
};

Thanks to range-v3 I can use the zip_with view (code not tested!)

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

But can I implement the begin() / end() methods using this view?

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();
    }
};

Can the two iterators (begin and end) safely compared?

The end result I want to achieve is the possibility to nest an arbitrary number of 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) { ... }
dvd
  • 1,014
  • 6
  • 12

1 Answers1

0

It looks like it is safe to do that, but it's probably easier to just store the zip_with_view<...> and not bother with binary_op.

note that your example isn't legal C++, because lambda expressions yield an object, not a type. You would need

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 };

At which point you might as well

auto r = view::zip_with(op2,
                        view::zip_with(op1, v1, v2),
                        v3);
Caleth
  • 52,200
  • 2
  • 44
  • 75
  • Yes, my code was broken (never post code without testing it :) ) I'll edit the question to remove the noise. – dvd Feb 23 '18 at 11:17
  • My main point is you are duplicating the return type of `zip_with` – Caleth Feb 23 '18 at 11:19
  • 1
    I think I'll follow your advice; I'll replace my class with a range view, checking the view value type where appropriated – dvd Feb 23 '18 at 11:45