I want to create some template which essentially should wrap it's parameter. The parameter should be an arbitrary function call, which gets wrapped via some template metaprogramming magic with prefix and postfix code.
I want to use it like follows:
auto result = try_call( some_vector.at(13) );
and try_call
would be defined somehow that it wraps a try..catch block around some_vector.at(13)
. Something like this:
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 that paper of Bjarne Stroustrup, but that's not exactly describing what I need, and I wasn't able to find a solution to this problem.
If this isn't possible directly, I am currently thinking of doing it via a templated function taking a lambda:
template<typename Func>
auto try_call(Func f) {
try {
return f();
} catch(std::exception&) {
return std::experimental::nullopt;
}
}
But I don't know if that's a good idea. The lambda has some overhead, I guess? I want to avoid any unneccessary overhead.
Actually, your solution with a lambda is quite good and efficient. From a type theoretic point of view, try_call
is a higher order function: It takes as argument another function and executes it in a try catch
context.
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;
}
}
Calling it with a lambda will yield what you want without any overhead. A lambda is compiled to an anonymous struct with an overloaded function call operator. This struct is used as template parameter for your try_call
function. Therefore, the compiler knows exactly the function to be executed when calling f()
and it will be inlined. No overhead involved.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With