Я читал учебное пособие Бена Хоффмана (https://benhoffman.tech/cpp/general/2018/11/13/cpp-job-system.html)
) Я пытался собрать вместе версию имеющейся у него системы Job / Worker, но вместо использования void*
для аргументов, приводящих затем к известной структуре, я пытался использовать переменные аргументы. Идея состоит в том, что задание получает «родителя» для выполнения метода, указатель функции на указанный метод и Args...
дляаргумент (ы). Однако, я получаю внутреннюю ошибку компилятора, если я пытаюсь построить. Вот класс задания:
template <class T, typename... Args>
struct JobMemberFunc : IJob
{
JobMemberFunc(T* aParent, void (T::* f)(Args...), Args... Args)
{
parentObj = aParent;
func_ptr = f;
saved_args = ::std::make_tuple (::std::move(Args)...);
}
virtual bool invoke() override
{
if (!parentObj) { return false; }
(parentObj->*func_ptr)(::std::move(saved_args));
return true;
}
/** the object to invoke the function pointer on */
T* parentObj;
/** The function pointer to call when we invoke this function */
void (T::* func_ptr)(Args...);
::std::tuple<Args...> saved_args;
};
struct CpuJob
{
IJob* jobPtr = nullptr;
};
Тогда есть метод AddJob, где внутренняя ошибка компилятора фактически происходит.
template <typename T, typename... Args>
void AddJob(T* aParent, void(T::* func_ptr)(Args...), Args... args)
{//This curly bracket is where the internal compiler error happens
CpuJob aJob = {};
JobMemberFunc<T, Args...>* jobPtr = new JobMemberFunc<T, Args...>(aParent, func_ptr,
std::forward<Args>(args)...);
aJob.jobPtr = jobPtr;
locklessReadyQueue.enqueue(aJob);
}
Более чем рад, что мне все равно говорят, что это плохой / неправильный способ попытаться сделать это. Я думал о том, чтобы покончить с этим и иметь стандартизированный список аргументов или сделать что-то полиморфное, но я действительнохочу сделать эту работу, чтобы я мог буквально попросить систему работы делать все, что мне нравится.
Спасибо!