1
votes

I've just started indulging myself in the advanced use of templates. I am trying to write a generalized wrapper for functions, to wrap functions that can cause exceptions. If no exception occurred the wrapper-function should write the actual return value to some reference and then return true. If an exception occurred it only returns false.

Code

#include <string>
#include <iostream>
#include <functional>
#include <exception>
#include <iomanip>

template<typename TReturn, typename ... TArgs>
bool Try(std::function<TReturn(TArgs...)> &function, typename std::function<TReturn(TArgs...)>::result_type& res, TArgs&...args) {
    try {
        res = function(std::forward<TArgs>(args)...);

        return true;
    }
    catch (...) {
        return false;
    }
}

std::string foo(int val) {
    if (val == 0) {
        throw std::exception();
    }

    return "result";
}

int main() {
    std::string res = "noResult";

    //Should be "false=>noResult"
    std::cout << std::boolalpha << Try(foo, res, 0) << "=>" << res;

    //Should be "true=>result"
    std::cout << std::boolalpha << Try(foo, res, 1) << "=>" << res;
}

Expectations

I expected a template instantiation like bool Try(std::function<std::string(int)>& function, std::string& res, int&arg);

Instead It doesn't even compile:

Errors:

no instance of function template "Try" matches the argument list

and

'bool Try(std::function<_Ret(_Types...)>,std::function<_Ret(_Types...)>::result_type &,TArgs &...)': could not deduce template argument for 'std::function<_Ret(_Types...)>' from 'std::string (int)'

I guess the way I call Try could also be flawed.


I found this simliar question but I can't get it to work with a return type.

And yes, there needs to be a special overload, for functions that return void.


What am I missing and how could this be done? Thanks in advance!
1
Have you tried calling Try like this: Try<TReturnType, ...>(foo, res, 0) ?Michael Smith
for one your Targs ... are slightly off, you probably meant to use '&&' over '&'Anycorn

1 Answers

2
votes

Why so many std::function?

template<typename TReturn, typename ... TArgs>
bool Try(TReturn (&function)(TArgs...), TReturn& res, TArgs...args) {
    try {
        res = function(std::forward<TArgs>(args)...);

        return true;
    }
    catch (...) {
        return false;
    }
}

Also you can't pass arguments like 0 as a reference TArgs&.... Just pass them as they are.