Reputation: 461
I have the following type alias:
using VoidFunc = void (*)();
I would like to define a class like so:
class SomeClass {
public:
template<template<typename Return, typename... Args>... Funcs>
static constexpr typename std::vector<VoidFunc> registerFunctions(Funcs<Return, Args...>... funcs) {
return { ((VoidFunc)(funcs), ...) };
}
};
I am aware that this is invalid syntax, as Return
and Args
are unresolvable outside of their template group. The goal is to allow the function registerFunction
to accept a variable number of functions all with different prototypes. In the actual implementation, it is important to preserve the type information of each function for use with other constexpr
functions. Is there a way to achieve this in C++17 or later?
Upvotes: 0
Views: 114
Reputation: 303067
You don't actually care about any of those underlying types (at least not in the code presented here). So just don't use it. All you care about is that these things are all function pointers:
typename <typename... F>
static std::vector<VoidFunc> registerFunctions(F*... funcs)
{
static_assert((std::is_function_v<F> && ...));
return { reinterpret_cast<VoidFunc>(funcs)... };
}
If you do need the signatures for something else, you can just pass each element of funcs
into a different function template and just re-deduce the actually signature there.
Note that the typename
is unnecessary there, and the constexpr
in C++17 makes this ill-formed (since you cannot in C++17 have a constexpr
std::vector
).
Upvotes: 4