1
나중에 실행할 수 있도록 매개 변수와 함께 일부 작업을 저장하는 코드를 작성했습니다. 코드 :"변수"로 매개 변수를 variadic 기반 템플릿에 전달할 수 없습니다.
class TaskInterface
{
public:
virtual void Execute() = 0;
};
namespace TaskHelper
{
template <std::size_t... Types>
struct index {};
template <std::size_t N, std::size_t... Types>
struct gen_seq : gen_seq<N - 1, N - 1, Types...> {};
template <std::size_t... Types>
struct gen_seq<0, Types...> : index<Types...>{};
}
template <typename ReturnType, typename... Types>
class SimpleTask : public TaskInterface
{
public:
template <typename Function>
SimpleTask(Function&& func, Types&&... args)
: m_function(std::forward<Function>(func)),
m_args(std::make_tuple(std::forward<Types>(args)...)) {
}
void Execute() override final
{
func(m_args);
}
private:
std::function<ReturnType(Types...)> m_function;
std::tuple<Types...> m_args;
template <typename... Args, std::size_t... Is>
void func(std::tuple<Args...>& tup, TaskHelper::index<Is...>)
{
m_function(std::get<Is>(tup)...);
}
template <typename... Args>
void func(std::tuple<Args...>& tup)
{
func(tup, TaskHelper::gen_seq<sizeof...(Args)>{});
}
};
template < typename ReturnType, class Class, typename... Types>
class MemberTask : public TaskInterface
{
public:
typedef ReturnType(Class::*Method)(Types...);
MemberTask(Class* object, Method method, Types&&... args) :
m_object(object), m_method(method), m_args(std::make_tuple(std::forward<Types>(args)...)) {
};
void Execute() override final
{
func(m_args);
};
private:
Class* m_object;
Method m_method;
std::tuple<Types...> m_args;
template <typename... Args, std::size_t... Is>
void func(std::tuple<Args...>& tup, TaskHelper::index<Is...>)
{
(m_object->*m_method)(std::get<Is>(tup)...);
}
template <typename... Args>
void func(std::tuple<Args...>& tup)
{
func(tup, TaskHelper::gen_seq<sizeof...(Args)>{});
}
};
template <typename Function, typename... Arguments>
TaskInterface* CreateSimpleTask(Function&& func, Arguments&&... args)
{
return new SimpleTask<typename std::result_of<decltype(func)(Arguments...)>::type, Arguments...>(std::forward<Function>(func), std::forward<Arguments>(args)...);
}
template <class Class, typename Method, typename... Arguments>
TaskInterface* CreateMemberTask(Class* obj, Method method, Arguments&&... args)
{
return new MemberTask<typename std::result_of<decltype(method)(Class)>::type, Class, Arguments...>(std::forward<Class*>(obj), std::forward<Method>(method), std::forward<Arguments>(args)...);
}
class Test {
public:
Test() { id = ++m_id; }
bool doIt(int n) {
std::cout << "doIt of " << n * id;
return true;
};
private:
static int m_id;
int id;
};
int Test::m_id = 0;
double test1(int xs)
{
xs *= 555;
return 66.02l;
}
그러나 문제는 내가에만이 방법으로 이러한 작업을 생성 할 수 있습니다 :
TaskInterface* st = CreateSimpleTask(test1, 5);
Test t;
TaskInterface* mt = CreateMemberTask(&t, &Test::doIt, 66);
을 할 수없는 이러한 방법 :
// error C2664: 'double (int)' : cannot convert argument 1 from 'int *' to 'int'
int xxxx;
TaskBase* st = CreateSimpleTask(test1, &xxxx);
또는 MemberTask에 대한 :
// cannot convert argument 2 from 'bool (__thiscall Test::*)(std::string)' to 'bool (__thiscall Test::*)(std::string &)'
std::string ss = "sdfsdf";
TaskBase* mt = CreateMemberTask(&t, &Test::doIt, ss);
어떻게 수정할 수 있습니까? y 클래스는 "value"뿐만 아니라 "variables"도 매개 변수를 전달할 수 있습니까? 또는이 모든 목적을 위해 내 "아키텍처"가 완전히 잘못 되었습니까?
저장하고 싶으면'std :: bind' 나 lambda를'std :: function'과 함께 사용해야합니다. 코드를 저장하는 것이 훨씬 간단합니다. – Holt
실제 줄과 전체 오류가 유용합니다. 오류를 이해하지 못한다면 오류를 편집하는 것은 좋지 않습니다. – Yakk
[C++ 17의 std :: apply'] (http : // ko)에 해당하는 [이 대답] (http://stackoverflow.com/a/20441189/1023390)을 보길 원할 수 있습니다. cppreference.com/w/cpp/utility/apply). – Walter