graham.reeds
graham.reeds

Reputation: 16476

Template deduction of return type

I have a function that will retry a function for a certain number of times and return whether it was successful:

template<typename Functor>
bool Attempt(Functor functor)
{
    bool success = false;
    size_t retries = MAX_RETRIES;
    do
    {
         success = functor();
    }
    while (!success && retries-- > 0);
    return success;
}

// usage:
bool success = Attempt([=]() {
    return something_that_may_not_work_the_first_time();
});

This works fine and is used through out the code where I need to retry something a multiple number of times (serial comms for example).

However I have recently needed to Attempt something that returns a std::optional<>.

What I came up with is this:

template <typename T, typename Functor>
std::optional<T> Attempt(Functor functor)
{
    std::optional<T> success{};
    size_t Retries = MAX_VALIDATION_RETRIES;
    do
    {
        success = functor();
    }
    while (!success && Retries-- > 0);
    return success;
}

// usage
std::optional<unsigned int> response = Attempt<unsigned int>([=]() {
    return something_that_returns_optional_unsigned_int();
});

Which works but is unsightly having the <unsigned int> on both sides of the assignment operator.

Is there any template chicanery that can be added to deduce that?

Upvotes: 3

Views: 104

Answers (1)

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122460

All the types you specify explicitly can be deduced:

#include <optional>

template <typename Functor>
auto Attempt(Functor functor)
{
    decltype(functor()) success{};
    size_t Retries = 42;
    do
    {
        success = functor();
    }
    while (!success && Retries-- > 0);
    return success;
}

std::optional<unsigned int> something_that_returns_optional_unsigned_int() { return {};};

int main() {
    auto response = Attempt([]{ return something_that_returns_optional_unsigned_int(); });
}

Upvotes: 4

Related Questions