Consider the following code snippet:
auto f = [](int x) { std::cout << x; };auto it =
boost::make_function_output_iterator(f);decltype(it) it2 = it; // Ok,
copied
it2 = it; // Does not compile, cannot assign!
The problem is, function_output_iterator constructed in this way is not
assignable, and thus does not satisfy the Iterator
http://en.cppreference.com/w/cpp/concept/Iterator concept, which requires
type to be CopyAssignable
http://en.cppreference.com/w/cpp/concept/CopyAssignable.
This is not a bug, since boost Function Output Iterator documentation
http://www.boost.org/doc/libs/1_60_0/libs/iterator/doc/function_output_itera...
clearly says
http://www.boost.org/doc/libs/1_60_0/libs/iterator/doc/function_output_itera...
:
UnaryFunction must be Assignable and Copy Constructible.
While assignment operator of a lambda function
http://en.cppreference.com/w/cpp/language/lambda is deleted:
ClosureType& operator=(const ClosureType&) = delete;
So this behaviour is technically correct, but for me is somewhat
unexpected. I think it is a perfectly reasonable desire to construct
function_output_iterator given a closure produced by lambda function. It
seems inconvenient to me why this use case causes a problem.
Can you suggest a workaround for this situation? Or maybe a way of
improving function_output_iterator to overcome this issue?
Personally, I came up with a trick to fix this in a situation, when I'm
sure iterator and its copies won't outlive the closure object. In this case
we may wrap closure with std::ref:
auto it = boost::make_function_output_iterator(std::ref(f));
This works quite fine, but obviously is not always possible.
Another options is to store closure in std::function:
std::function