On 4 Feb 2016 at 23:02, Domagoj Saric wrote:
You could theoretically pass exceptions function-to-function by exception_ptr but that seems backwards, no pun intended. :)
And we could theoretically and practically ;) return actual error objects (even those considered 'exceptions', e.g. std::runtime_error) w/o necessarily stuffing them into some type erasing mechanism like exception_ptr (i.e. you pass the ball as a ball until you need to interact with someone who only understands abstract UFOs;)
exception_ptr is like shared_ptr - the potential use of atomics forces the compiler to emit code just in case. Any potential use of atomics is like calling fsync() on the compiler's AST.
https://github.com/psiha/err/blob/master/include/boost/err/errno.hpp https://github.com/psiha/err/blob/master/include/boost/err/win32.hpp
Firstly I just found and read your RFC on this potential Boost.Err at http://lists.boost.org/Archives/boost/2015/11/226558.php. You posted this during my vacation away from Boost, so I didn't see it till now. I'd like to thank you for this contribution to the debate, it certainly is original. There are some very interesting - perhaps even debatable - feature choices in this object. I'll skip commenting on most of those, but I will say one thing - I've found in AFIO v2 the ability to use outcome::result<T> as a receiving container surprisingly useful. The pattern looks like this: 1. User hands some scatter buffers to be filled by a file_handle::async_read() to AFIO v2. These probably are a std::vector<std::pair<char *, size_t>>. 2. AFIO dynamically allocates a file_handle::io_state to represent the i/o (memory allocation is unavoidable, but in AFIO v2 there is exactly one memory allocation and deallocation per i/o now, unlike eight allocations and deallocations in v1) and move constructs the user's scatter buffers into an outcome::result<std::vector<std::pair<char *, size_t>>> living inside the file_handle::io_state. 3. For each completing buffer in the scatter list, if there was an error we set the outcome::result<> to that error. If not errored and the outcome::result<> does not hold an error, we update the buffer with the transfer achieved. 4. Once all buffers are completed, we invoke whatever completion handler of type U&& the user specified, passing through the file_handle::io_state. In other words, I found my result<T> very useful as a state accumulator which can "go errored" in a natural way. Some may note that we throw away all errors but the first received one, but that's fine in this use case - I cannot think of a use case where an end user cares if parts of a scatter-gather operation succeed and others fail, if they did they'd split up the scatter-gather list into separate operations. Your Err object can't do value semantics - it cannot be a container in its own right. I personally think that is unfortunate for the reasons above. I think there is much more usefulness in these objects having full value semantics BUT with a restricted variant content, so basically either it's the value you want OR it's why there isn't a value you expect there. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/