Let's assume I have a collection of functions following the following pattern:
template <typename T, typename ... Args>
T example(Args ... args, T* defaultValue);
Furthermore I have another function that operates on these collections:
template <auto Function, typename T, typename ... Args>
auto transform(Args ... args) {
// ...
T defaultValue /* = ... */;
auto result = Function(args... , &defaultValue);
// ...
return result;
}
For example the transform
function can be used like
auto result = transform<ExampleFunction, ExampleT>(int a, int b, int c);
The compiler completes the types for Args
. But I have the problem that I have to specify T
. However I know that T
is always the last type of the parameters of Function
.
Is there a way to "teach" the compiler this property so I can call the transform
function without specifying T
?
auto result = transform<ExampleFunction>(int a, int b, int c);
Example
In vulkan there are these functions vkEnumerateInstanceExtensionProperties
and such. You always have to call these functions twice to retrieve some data. I want to create a function listify
which returns this data as vector.
template <auto Function, typename T, typename ... Args>
auto listify(Args ... args)
{
uint32_t size;
Function(args... , &size, nullptr);
std::vector<T> result(size);
Function(args... , &size, result.data());
return result;
}
I would like to call this function like so
auto result = listify<vkEnumerateInstanceExtensionProperties>(nullptr);
CodePudding user response:
You can get the parameters from function.
for example you can do something like this
#include <tuple>
template<typename F>
struct last_arg{};
template<typename ret, typename ...args>
struct last_arg<ret(*)(args...)>{
using type = std::tuple_element_t<sizeof...(args)-1,std::tuple<args...>>;
};
template <auto F, typename ...Args>
auto f(Args... args) {
using T=std::remove_pointer_t<typename last_arg<decltype(F)>::type>;
T defaultValue;
auto result = F(args... , &defaultValue);
return result;
}
int bar(int,int*);
void foo(){
f<bar>(1);
}
(this assumes the function is not a function object, but that's also possible)