
Cloning exceptions is out of the scope of Boost Exception. See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2179.html.
I wish that there was a way to get this functionality into boost::exception or boost::thread sooner than 0x. The exception constructor populates a thread-local pointer or something...
In my opinion, compile-time type safety is especially important in the case of boost::exception. [...] the error handling paths of any program are the hardest to test; catching any error-handling bug at compile time is very valuable.
Since there is a possibility that the tag was not used, we get the same number of control paths in the catch block in both the static-type keys and string-based keys. So there probably wouldn't be much difference in testing effort. On the other hand, a visitor interface would eliminate the branch: bool retry(false); do { try { throw my_error() << boost::error_info<tag_errno>(errno); } catch(exception& e) { using namespace boost::lambda; std::string filename("no-name"); //Set retry if we have a tag_errno whose value is EAGAIN //and get the filename from the tag_filename field. e.visit_tags(e , exception::for_tag<tag_errno>(if_then(_1==EAGAIN,var(retry)=true)) ||exception::for_tag<tag_filename>(var(filename)=_1) ); cout<<"There was an error with file named " << filename << ". We will "; if(!retry) cout << "not "; cout<<"retry.\n"; } }while(retry); The (visitor) pattern would apply to string id or description matching style of identifying fields. There is only one obvious behavior for the case where a tag is inserted more than once: the callback is invoked for each value.
throw exception() << "Something went wrong. value=" << value;
This approach is inappropriate in general, because the actual formatting of the text is locale-specific and is best done when handling the exception, not when throwing.
When throwing, the values would be copied (and maybe dynamically allocated, if the type fails has_nothrow_copy), but no formatting applied. Formatting is only applied when exception::what() is called. No matter whether types, string ids or fragments of description strings are used as keys, it is handy to be able to interleave descriptive text with the data fields at the throw site. This is helpful when debugging, since it minimizes the effort required to get descriptive error messages.