The first attempt to accommodate the User Requirements might result in the following fairly conventional interface:
template<typename Out, typename In> Out convert (In const&); //#1 template<typename Out, typename In> Out convert (In const&, Out const& fallback); //#2 template<typename Out, typename In> bool convert (Out& result_out, In const&); //#3 template<typename Out, typename In> bool convert (Out& result_out, In const&, Out const& fallback); //#4
with the following behavior:
result_out
            (when successful), returns indication of success or failure (R3b,
            R5, R5a but not R5c);
          result_out
            (when successful) or the provided fallback, returns indication of success
            or failure (R3b, R5, R5c
            and R5a).
          
        The #3 and #4 signatures are special as they, in fact, return two things
        -- the actual result (written into the result_out)
        and the indication of success or failure (returned by the functions). Given
        that a reference to result_out
        is passed in, the actual result_out
        instance is constructed (storage allocated and initialized) outside the function
        calls.
      
Similar to the scenario described in the Converter Signature section that results in an additional and unnecessary overhead. Indeed, if the conversion operation succeeds, then the initialization value is overridden (with the actual result), if it fails, then the value is either overridden still (with the fallback) or is meaningless.
        To avoid the overhead we might again (as in the Converter
        Signature section) deploy boost::optional
        and to change the signatures to
      
bool convert (boost::optional<Out>&, In const&); //#3 bool convert (boost::optional<Out>&, In const&, Out const&); //#4
        Now, when we look at #3, we can see that the indication of success or failure
        is duplicated. Namely, it is returned from the function and is encapsulated
        in boost::optional<Out>.
        Consequently, #3 can be further simplified to
      
void convert (boost::optional<Out>&, In const&); //#3
or expressed more idiomatically (in C++) as:
boost::optional<Out> convert (In const&); //#3
So far, we have arrived to the following set
Out convert (In const&); //#1 Out convert (In const&, Out const&); //#2 boost::optional<Out> convert (In const&); //#3 bool convert (boost::optional<Out>&, In const&, Out const&); //#4
which as a whole looks quite ugly and, in fact, does not even compile as #1 clashes with #3. The good thing though is that functionally #1 and #2 are not needed anymore as they are duplicates of the following #3 deployments:
Out out1 = boost::convert(in).value(); // #3 with #1 behavior Out out2 = boost::convert(in).value_or(fallback); // #3 with #2 behavior
Again, we are not discussing aesthetic aspects of the interface (or syntactic sugar some might say, which might be very subjective). Instead, we are focusing on the functional completeness and so far we manage to maintain the same functional completeness with less.
Turns out, with a bit of effort, we can get away without the most complex one -- #4 -- as well:
boost::optional<Out> out = boost::convert(in); bool out_success = out ? true : false; Out out_value = out.value_or(fallback);
So, ultimately we arrive to one and only
boost::optional<Out> convert(In const&);
        The important qualities of the API are that it is functionally-complete
        and the most efficient way to deploy the chosen converter
        signature (see the Converter
        Signature section). Namely, the boost::convert() interface is routinely optimized out (elided)
        when deployed as
      
boost::optional<Out> out = boost::convert(in);
        The API has several deployment-related advantages. First, it says exactly
        what it does. Given a conversion request is only a request,
        the API returns boost::optional essentially saying "I'll
        try but I might fail. Proceed as you find appropriate.". Honest and
        simple. I prefer it to "I'll try. I might fail but you do not want to
        know about it." or "I'll try. If I fail, you die." or variations
        along these lines. :-)
      
        On a more serious note though the interface allows for batched conveyor-style
        conversions. Namely, attempting to convert several values, in sequence, storing
        the boost::optional results and, then, analyzing/validating
        them (without losing the information if each individual conversion was successful
        or not) in some semi-automated way.
      
Again, that API does not have to be the only API Boost.Convert provides. However, that API is the only essential API. Other APIs are relatively easily derived from it. For example,
template<typename Out, typename In> Out convert(In const& in, Out const& fallback) //#2 { return convert(in).value_or(fallback); }
Given that it is extremely difficult (if not impossible) to come up with a library API that could please everyone, we might as well settle on the essential API and let the users build their own APIs (as in the example above) to satisfy their aesthetic preferences.
        Still, it needs to be acknowledged that boost::optional
        is a fairly new concept and some people are reluctant using it or find its
        deployment unreasonably complicating. Consequently, Boost.Convert
        provides an alternative (more conventional) interface:
      
Out convert(In const&, Converter const&, Out const& fallback_value); Out convert(In const&, Converter const&, Functor const& fallback_functor); Out convert(In const&, Converter const&, boost::throw_on_failure);