RxCpp
RxCpp copied to clipboard
Compile-error using tap (but not with subscribe)
Hi :-),
I was trying to move all side-effects in my application into taps instead of in the subscribe methods;
However, the following snippet does not compile:
typedef std::pair<int, int> dataMsg;
auto loop = rxcpp::synchronize_event_loop();
auto data = rxcpp::subjects::subject<dataMsg>();
auto dataSubscriber = data.get_observable();
auto time = rxcpp::observable<>::interval(10ms);
// create data through measurements
time
.subscribe_on(loop)
.map([&](int v){
return std::make_pair(v, 5*v);
})
.tap(
[&data](const auto& measurement){data.on_next(measurement);},
// [](std::exception_ptr ep){printf("Tap - OnError: %s\n", rxcpp::util::what(ep).c_str());}
)
.subscribe();
while the following does:
typedef std::pair<int, int> dataMsg;
auto loop = rxcpp::synchronize_event_loop();
auto data = rxcpp::subjects::subject<dataMsg>();
auto dataSubscriber = data.get_observable();
auto time = rxcpp::observable<>::interval(10ms);
// create data through measurements
time
.subscribe_on(loop)
.map([&](int v){
return std::make_pair(v, 5*v);
})
.tap(
[&data](const auto& measurement){data.on_next(measurement);},
[](std::exception_ptr ep){printf("Tap - OnError: %s\n", rxcpp::util::what(ep).c_str());}
)
.subscribe();
A part of the compile error is:
required from here
/usr/local/include/rxcpp/rx-observer.hpp:439:13: error: no matching function for call to ‘rxcpp::detail::virtual_observer<std::pair<double, double> >::on_next(std::__exception_ptr::exception_ptr)’
destination->on_next(std::forward<V>(v));
^~~~~~~~~~~
/usr/local/include/rxcpp/rx-observer.hpp:353:18: note: candidate: void rxcpp::detail::virtual_observer<T>::on_next(T&) const [with T = std::pair<double, double>]
virtual void on_next(T&) const {};
^~~~~~~
/usr/local/include/rxcpp/rx-observer.hpp:353:18: note: no known conversion for argument 1 from ‘std::__exception_ptr::exception_ptr’ to ‘std::pair<double, double>&’
/usr/local/include/rxcpp/rx-observer.hpp:354:18: note: candidate: void rxcpp::detail::virtual_observer<T>::on_next(T&&) const [with T = std::pair<double, double>]
virtual void on_next(T&&) const {};
^~~~~~~
/usr/local/include/rxcpp/rx-observer.hpp:354:18: note: no known conversion for argument 1 from ‘std::__exception_ptr::exception_ptr’ to ‘std::pair<double, double>&&’
But it is not clear to me why this happens (if I look at the rxcpp twitter-example, I do not see the OnError explicitly defined in the tap-operators for instance..).
Looks like a bug in the design of the make_observer overloads. See the overloads for DefaultOnError that are used by tap. There are multiple work arounds to disambiguate this. Specifying the error method (either as a function or the built in OnErrorIgnore), specifying the value argument type explicitly, calling make_observer directly with unambiguous args, etc..
Avoiding the auto in the tap indeed also helps.
In an attempt to learn, I'll toy around to see if I can come up with a pr that allows auto..