Problem with storing forward references(universal) to be forward and used later
I'm writing a class where I can pass any function pointer with its argument types and return type, and later call the .Launch()
method and forward the parameters for invoking the function later. I'm having problem making it accepting any type of parameters with forward references.
I'm using std::tuple to save to parameters and std::function to save the function pointer, std::apply to invoke the function with saved parameters in tuple. This is by the way simplified version of the class.
#include <functional>
#include <tuple>
#include <vector>
template <typename R, typename... Args>
class AnyWorker
{
public:
AnyWorker(std::function<R(Args...)>&& in_pFunction)
:pFunction{ in_pFunction }
{
}
//why not "Args&&..." here?
R Launch(Args... inArgs)
{
savedArgs = std::make_tuple(std::forward<Args>(inArgs)...);
return Work();
}
private:
R Work()
{
return std::apply(pFunction, savedArgs);
}
private:
std::function<R(Args...)> pFunction;
std::tuple<Args...> savedArgs;
};
int modifyVec1(std::vector<int> vec)
{
int add{ 1 };
for (int i{ 0 }; i < vec.size(); ++i)
vec[i] += add;
return 678;
}
std::vector<int> modifyVec2(std::vector<int>&& vec)
{
std::vector<int> workingVec{vec};
int add{ 1 };
for (int i{ 0 }; i < vec.size(); ++i)
workingVec[i] += add;
return workingVec;
}
int modifyVec3(std::vector<int>* vec)
{
int add{ 1 };
for (int i{ 0 }; i < vec->size(); ++i)
(*vec)[i] += add;
return 985;
}
int modifyVec4(std::vector<int>& vec)
{
int add{ 1 };
for (int i{ 0 }; i < vec.size(); ++i)
vec[i] += add;
return 722;
}
int main()
{
std::vector<int> vec{ 1, 2, 3 };
std::vector<int> vec2{ 10, 20, 30 };
std::vector<int> vec3;
std::vector<int> vec4;
//-----------------why not "std::vector<int>&&" here?
AnyWorker<std::vector<int>, std::vector<int>> myWorker(modifyVec2);
vec3 = std::move(myWorker.Launch(std::move(vec)));
vec4 = std::move(myWorker.Launch(std::move(vec2)));
AnyWorker<int, std::vector<int>*> myWorker2(modifyVec3);
auto result = myWorker2.Launch(&vec3);
result = myWorker2.Launch(&vec4);
AnyWorker<int, std::vector<int>> myWorker3(modifyVec1);
auto result2 = myWorker3.Launch(vec3);
result2 = myWorker3.Launch(vec4);
//AnyWorker<int, std::vector<int>&> myWorker4(modifyVec4);
//auto result3 = myWorker4.Launch(vec);
//result3 = myWorker4.Launch(vec2);
}
Edit: I have managed to make it work with rvalue references and pointer and simple copy values but couldn't do it with lvalue reference.
I also don't realize why I can't use forwarding references in variadic template .launch()
if do use it will work for rvalue references and pointers but not simple copy values.
While trying to compile the with the modifyVec4 function I get the error :
'std::tuple<std::vector<int,std::allocator<int>> &>::tuple': no appropriate default constructor available
I have also checked this post Storing variable arguments to be forwarded later but I can't seem to find where I am doing wrong with forward references.