C++ Logo

std-proposals

Advanced search

Fwd: Middle ground between "return" and exceptions?

From: Dusan Jovanovic (DBJ) <"Dusan>
Date: Mon, 14 Sep 2020 23:39:47 +0200
Bary's proposal I will study carefully, but here is mine completely
different one

 template<typename T> struct valstat final {
        T* value;
        std::errc status;
    };

    valstat<const char> FindUsersCity() noexcept
    {
        if (auto [contacts, errc] =
GetOrOpenContactsServerConnection(); contacts)
        {
            if (auto [uid, errc] = contacts->GetUserId(); uid) {
                if (auto [geo, errc] = GetOrOpenGeoServerConnection(); geo) {
                    if (auto [uloc, errc] = geo->GetLocation(uid); uloc) {
                        return uloc->GetCityName();
                    }
                    else {
                        return { {}, errc };
                    }
                }
                else {
                    return { {}, errc };
                }
            }
            else {
                return { {}, errc };
            }
        }
        else {
            return { {}, errc };
        }
    }

No Result, Expected, Outcome, no exceptions and no std lib either…

auto [city_name, errc] = FindUsersCity();

On Mon, 14 Sep 2020 at 21:20, Dmitry Dmitry via Std-Proposals <
std-proposals_at_[hidden]> wrote:

>
>>> However, what you want is already possible in Standard C++:
>>
>> std::optional<std::string> FindUsersCity() {
>> try {
>> std::optional<ContactsServer> contacts =
>> GetOrOpenContactsServerConnection();
>> std::optional<UserId> uid = contacts.value().GetUserId(); //
>> throw bad_optional_access on empty
>> std::optional<GeoServer> geo = GetOrOpenGeoServerConnection();
>> std::optional<Location> uloc =
>> geo.value().GetLocation(uid.value()); // throw bad_optional_access on empty
>> return uloc.value().GetCityName();
>> } catch (const std::bad_optional_access&) {
>> return std::nullopt;
>> }
>> }
>>
>>
> If you want the same level of flexibility as with returns (and you usually
> want, because sometimes you need to be more specific and capture some
> context/explanation), then it would be:
> Result<int, std::string> FindUsersCity() {
> std::optional<ContactsServer> contacts
> = GetOrOpenContactsServerConnection();
> std::optional<UserId> uid;
> try {
> uid = contacts.value().GetUserId(); // throw bad_optional_access
> on empty
> } catch (const std::bad_optional_access&) {
> return failure("failed to get GetOrOpenContactsServerConnection:
> details: " + ...)
> }
> std::optional<GeoServer> geo = GetOrOpenGeoServerConnection();
> try {
> std::optional<Location> uloc =
> geo.value().GetLocation(uid.value()); // throw bad_optional_access on empty
> } catch (const std::bad_optional_access&) {
> return failure("failed to get GetOrOpenGeoServerConnection:
> details: " + ...)
> }
> try {
> return uloc.value().GetCityName();
> } catch (const std::bad_optional_access&) {
> return failure("failed to get GetLocation of: " + ...)
> }
> }
>
> --
> Dmitry
> *Sent from gmail*
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2020-09-14 16:40:11