Let's say we have this simplified version of my code:
template<typename R>
R Context::executeTransient(std::function<R(VkCommandBuffer)> const &commands) {
...
R result = commands(commandBuffer);
...
return result;
}
I tried to pass a lambda function as a parameter to the function Context::executeTransient()
but it works only if I explicitly assign the lambda to a specific std::function
type. This works:
std::function<int(VkCommandBuffer)> f = [](VkCommandBuffer commandBuffer) {
printf("Test execution");
return 1;
};
context.executeTransient(f);
The example above works but I'd like to achieve the example below because of aesthetic reasons and don't know if this is even possible:
context.executeTransient([](VkCommandBuffer commandBuffer) {
printf("Test execution");
return 1;
});
My only requirement is that Context::executeTransient()
should accept lambdas and functions with a templated return type and input argument with some specific type e.g. VkCommandBuffer
.
What about simply as follows ?
template <typename F>
auto Context::executeTransient (F const & commands) {
...
auto result = commands(commandBuffer);
...
return result;
}
This way your method accept both standard functions and lambdas (without converting them to standard functions, that is preferable, from the performance point of view (as far as I know)) and the return type is deduced from the use (auto
).
In you need to know the R
type inside the method, you can apply decltype()
to result
auto result = commands(commandBuffer);
using R = decltype(result);
If you need to know the R
type as template parameter of the method, its a little more complex because involve std::declval()
and, unfortunately, add redundancy
template <typename F,
typename R = decltype(std::declval<F const &>()(commandBuffer))>
R Context::executeTransient (F const & commands) {
...
R result = commands(commandBuffer);
...
return result;
}