1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 2<html><meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 3<title>Incommensurate E types - Boost.Outcome documentation</title> 4<link rel="stylesheet" href="../../../css/boost.css" type="text/css"> 5<meta name="generator" content="Hugo 0.52 with Boostdoc theme"> 6<meta name="viewport" content="width=device-width,initial-scale=1.0"/> 7 8<link rel="icon" href="../../../images/favicon.ico" type="image/ico"/> 9<body><div class="spirit-nav"> 10<a accesskey="p" href="../../../tutorial/advanced/interop.html"><img src="../../../images/prev.png" alt="Prev"></a> 11 <a accesskey="u" href="../../../tutorial/advanced/interop.html"><img src="../../../images/up.png" alt="Up"></a> 12 <a accesskey="h" href="../../../index.html"><img src="../../../images/home.png" alt="Home"></a><a accesskey="n" href="../../../tutorial/advanced/interop/value-or-error.html"><img src="../../../images/next.png" alt="Next"></a></div><div id="content"> 13 <div class="titlepage"><div><div><h1 style="clear: both">Incommensurate E types</h1></div></div></div> 14 <p>Back in the essential tutorial section on <code>result</code>, we studied a likely very common 15initial choice of <code>E</code> type: <a href="../../../tutorial/essential/result.html">a strongly typed enum</a>. 16We saw how <a href="../../../motivation/plug_error_code.html">by marking up strongly typed enums to tell the C++ standard library 17what they are</a>, they gain implicit convertibility into <code>std::error_code</code>, and we 18then pointed out that you might as well now always set <code>E = std::error_code</code>, as that 19comes with the enormous advantage that you can use the boilerplate saving 20<code>BOOST_OUTCOME_TRY</code> macro when the <code>E</code> type is always the same.</p> 21 22<p>We thus strongly recommend to users that for any given piece of code, always 23using the same <code>E</code> type across the codebase is very wise, except where you explicitly want 24to prevent implicit propagation of failure up a call stack e.g. local failures in 25some domain specific piece of code.</p> 26 27<p>However it is unreasonable to expect that any non-trivial codebase can make do 28with <code>E = std::error_code</code>. This is why Outcome allows you to use <a href="../../payload">custom <code>E</code> 29types which carry payload</a> in addition to an error code, yet 30still have that custom type treated as if a <code>std::error_code</code>, including <a href="../../payload/copy_file3">lazy custom exception 31throw synthesis</a>.</p> 32 33<p>All this is good, but if library A uses <code>result<T, libraryA::failure_info></code>, 34and library B uses <code>result<T, libraryB::error_info></code> and so on, there becomes 35a problem for the application writer who is bringing in these third party 36dependencies and tying them together into an application. As a general rule, 37each third party library author will not have built in explicit interoperation 38support for unknown other third party libraries. The problem therefore lands 39with the application writer.</p> 40 41<p>The application writer has one of three choices:</p> 42 43<ol> 44<li><p>In the application, the form of result used is <code>result<T, std::variant<E1, E2, ...>></code> 45where <code>E1</code>, <code>E2</code> … are the failure types for every third party library 46in use in the application. This has the advantage of preserving the original 47information exactly, but comes with a certain amount of use inconvenience 48and maybe excessive coupling between high level layers and implementation detail.</p></li> 49 50<li><p>One can translate/map the third party’s failure type into the application’s 51failure type at the point of the failure 52exiting the third party library and entering the application. One might do 53this, say, with a C preprocessor macro wrapping every invocation of the third 54party API from the application. This approach may lose the original failure detail, 55or mis-map under certain circumstances if the mapping between the two systems 56is not one-one.</p></li> 57 58<li><p>One can type erase the third party’s failure type into some application 59failure type, which can later be reconstituted if necessary. This is the cleanest 60solution with the least coupling issues and no problems with mis-mapping, but 61it almost certainly requires the use of <code>malloc</code>, which the previous two did not.</p></li> 62</ol> 63 64<p>Things get even more complicated in the presence of callbacks. If in the 65callback you supply to library A, you call library B, you may need to insert 66switch statement maps or other mechanisms to convert library B’s failures into 67something library A can understand, and then somehow extract that out – preferably 68without loss of original information – into the application’s failure handling 69mechanism if library A subsequently returns failure as well. This implies 70transmitting state by which to track these interrelated pieces of failure data.</p> 71 72<p>Let us see what Outcome can do to help the application writer address some of these 73issues, next.</p> 74 75 76 </div><p><small>Last revised: February 09, 2019 at 15:18:26 UTC</small></p> 77<hr> 78<div class="spirit-nav"> 79<a accesskey="p" href="../../../tutorial/advanced/interop.html"><img src="../../../images/prev.png" alt="Prev"></a> 80 <a accesskey="u" href="../../../tutorial/advanced/interop.html"><img src="../../../images/up.png" alt="Up"></a> 81 <a accesskey="h" href="../../../index.html"><img src="../../../images/home.png" alt="Home"></a><a accesskey="n" href="../../../tutorial/advanced/interop/value-or-error.html"><img src="../../../images/next.png" alt="Next"></a></div></body> 82</html> 83