Wrap an arbitrary function call through metaprogramming a template using a try..catch block in modern C ++

I want to create some template, which essentially should wrap it with a parameter. The parameter must be an arbitrary function call, which is wrapped using a magic metaprogramming template with a prefix and a postfix code.

I want to use it as follows:

auto result = try_call( some_vector.at(13) );

and try_callwill be determined in some way that it completes the try..catch block around some_vector.at(13). Something like that:

template<typename T>
// some template metaprogramming magic here
try {
    auto value = // execute the parameter here, i.e. some_vector.at(13);
    return std::experimental::optional<T>(value);
} 
catch (std::exception&) {
    return std::experimental::nullopt;
}

There is an article by Bjarne Straustrup, but this is not an exact description of what I need, and I could not find a solution to this problem.

If this is not possible directly, I am currently thinking about it through a template function taking a lambda:

template<typename Func>
auto try_call(Func f) {
    try {
        return f();
    } catch(std::exception&) {
        return std::experimental::nullopt;
    }
}

, . , ? .

+4
2

, . try_call : try catch.

template<typename Func>
auto try_call(Func f) -> std::experimental::optional<std::decay_t<decltype(f())>> {
    try {
        return std::experimental::make_optional(f());
    } catch(std::exception&) {
        return std::experimental::nullopt;
    }
}

, , - . . try_call. , f(), . .

+5

; , .

// Function
template<typename ReturnType, typename... Args, typename... UArgs>
ReturnType no_throw_call(ReturnType (*f)(Args...), UArgs... args)
{
    try { return f(args...); }
    catch (...) {}
    return ReturnType();
}

// Method
template<typename ReturnType, typename Class, typename... Args, typename... UArgs>
ReturnType no_throw_call_method(Class &c, ReturnType(Class::*m)(Args...), UArgs... args)
{
    try { return (c.*m)(args...); }
    catch (...) {}
    return ReturnType();
}

: UArg , , .

, .

, , - . , QA.

, , , QA. undefined, , .

:

#define nt_strcpy(X,Y) no_throw_call(strcpy, (X), (Y))
nt_strcpy(nullptr, nullptr);

B b;
// this calls a method named do_it which takes an int as a parameter and returns void
no_throw_call_method<void>(b, &B::do_it, 1);
0

Source: https://habr.com/ru/post/1598771/


All Articles