여기서 원하는 작업을 수행하려면 템플릿 인수를 튜플에 저장해야합니다.
std::tuple<Ts...> args;
또한 생성자를 약간 변경해야합니다. 특히로 초기화 args
하고 std::make_tuple
매개 변수 목록에서 범용 참조를 허용합니다.
template <typename F, typename... Args>
Action(F&& func, Args&&... args)
: f(std::forward<F>(func)),
args(std::forward<Args>(args)...)
{}
또한 다음과 같이 시퀀스 생성기를 설정해야합니다.
namespace helper
{
template <int... Is>
struct index {};
template <int N, int... Is>
struct gen_seq : gen_seq<N - 1, N - 1, Is...> {};
template <int... Is>
struct gen_seq<0, Is...> : index<Is...> {};
}
그리고 이러한 생성기를 사용하는 방식으로 메서드를 구현할 수 있습니다.
template <typename... Args, int... Is>
void func(std::tuple<Args...>& tup, helper::index<Is...>)
{
f(std::get<Is>(tup)...);
}
template <typename... Args>
void func(std::tuple<Args...>& tup)
{
func(tup, helper::gen_seq<sizeof...(Args)>{});
}
void act()
{
func(args);
}
그리고 그것! 이제 수업은 다음과 같이 보일 것입니다.
template <typename... Ts>
class Action
{
private:
std::function<void (Ts...)> f;
std::tuple<Ts...> args;
public:
template <typename F, typename... Args>
Action(F&& func, Args&&... args)
: f(std::forward<F>(func)),
args(std::forward<Args>(args)...)
{}
template <typename... Args, int... Is>
void func(std::tuple<Args...>& tup, helper::index<Is...>)
{
f(std::get<Is>(tup)...);
}
template <typename... Args>
void func(std::tuple<Args...>& tup)
{
func(tup, helper::gen_seq<sizeof...(Args)>{});
}
void act()
{
func(args);
}
};
다음은 Coliru에 대한 전체 프로그램입니다.
업데이트 : 다음은 템플릿 인수를 지정할 필요가없는 도우미 메서드입니다.
template <typename F, typename... Args>
Action<Args...> make_action(F&& f, Args&&... args)
{
return Action<Args...>(std::forward<F>(f), std::forward<Args>(args)...);
}
int main()
{
auto add = make_action([] (int a, int b) { std::cout << a + b; }, 2, 3);
add.act();
}
그리고 또 다른 데모가 있습니다.