I have a program making use of boost::signals2
. I need to return a non-copyable value. In order to achieve this, I tried to change the combiner template parameter. The curious thing about this is that inside the combiner I get an error.
This works:
struct Combiner {
using result_type = NonCopyable;
template <class Iter>
NonCopyable operator()(Iter b, Iter e) {
return NonCopyable(something);
}
};
using SignalType = boost::signals2::signal<NonCopyable (), Combiner>;
But at the moment I try to dereference an iterator inside Combiner::operator()
, things get messed up.
struct Combiner {
using result_type = NonCopyable;
template <class Iter>
NonCopyable operator()(Iter b, Iter e) {
return *b;
}
};
std::is_const<Iter>
returns false.
std::is_reference<decltype(*b)>
is returning true.
I cannot figure out why I have the error, but I see the wrong overload is selected here:
void assign_value(argument_type val) { get_impl() = val; }
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
void assign_value(rval_reference_type val) { get_impl() = static_cast<rval_reference_type>(val); }
#endif
Rvalue references are activated, I checked it in an example program and I am using c++14 flag in gcc. Any idea?
EDIT: Full example.
#include <memory>
#include <boost/signals2.hpp>
class NonCopyable {
std::unique_ptr<int> _i;
public:
explicit NonCopyable(int i) : _i(new int(i)) {}
};
struct Combiner {
using result_type = NonCopyable;
template <class Iter>
NonCopyable operator(Iter b, Iter b) const {
return std::move(*b);
}
};
using SignalType = boost::signals2::signal<NonCopyable(), Combiner>;
int main() {
SignalType s;
s.connect([] { return NonCopyable(3); });
s();
}