Reputation: 664
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?
Upvotes: 2
Views: 707
Reputation: 39774
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;
Upvotes: 2