I have a class that creates an std::function
. For simplicity, I'll say the std::function
returns a boolean for this example. The std::function
needs to take in a variadic tuple. Currently, I have
template<class... FuncArgs>
class Function
{
public:
// Type that std::function returns
using func_ret_ty = bool;
private:
std::function<func_ret_ty(std::tuple<FuncArgs...>)> m_Function;
std::tuple<FuncArgs...> m_Args; // Stores m_Function's arguments
public:
Function(
std::function<func_ret_ty(std::tuple<FuncArgs...>)> function,
FuncArgs... args)
: m_Function(function)
, m_Args(std::make_tuple(std::forward<FuncArgs>(args)...))
{}
};
My question is simple: will this work?
More specifically, I'm concerned because there seems to be a circular dependency in declaring the type for function
. Another thought for implementation I had was:
template<class FuncTy, class FuncArgs...>
class Function
{
public:
using func_ret_ty = bool;
private:
FuncTy m_Function;
std::tuple<FuncArgs...> m_Args;
public:
Function(
FuncTy function,
FuncArgs... args)
: m_Args(std::make_tuple(std::forward<FuncArgs>(args)...))
{
static_assert(
std::is_same_v<FuncTy, std::function<func_ret_ty(std::tuple<FuncArgs...>)>>,
"FuncTy invalid type!"
);
m_Function = std::move(function);
}
};
Is the second implementation better? Is there a better way to go about doing this?
The first implementation looks better to me, because you don't have to repeat yourself by providing the function arguments twice.
Because you set the return type to bool
, I would recommend changing the name of the class to Predicate
, which is a well known term to describe functions that return boolean values.
Note that std::function
can take parameter packs as template parameters too, so you can also do this:
std::function<func_ret_ty(FuncArgs...)> m_Function;