Here's how I tried to solve it:
The parametr package can be recursively extended and each parameter is saved. A functional store should do this. It uses one (double overloaded) helper function.
template<typename T> void storeHelperFunction(void*& memory, T last) { *((T*)memory) = last; memory = (void*)((char*)memory + sizeof(T)); } template<typename T, typename... Params> void storeHelperFunction(void*& memory, T first, Params... rest) { storeHelperFunction(memory, first); storeHelperFunction(memory, rest...); } template<typename... Params> void store(void* memory, Params... args) {
The function store takes a pointer to memory, where it is supposed to store the number of varialbe arguments.
A pointer can point to some dynamically allocated memory or a label to a structure whose size is equal to sizeof...(Params) . Such a structure, which has exactly any desiared size, can be constructed using template metaprogramming:
template <int N> struct allocatorStruct { char byte1; allocatorStruct<N-1> next; }; template <> struct allocatorStruct<1> {};
I'm not sure what the standard says or as compilers of other compilers than Microsoft compilation. But using my compiler, sizeof (allocatorStruct) is N for any N that is greater than or equal to 1.
Therefore, allocatorStruct<sizeof...(Params)> is the same size as Params.
Another way to create something the same size as Params is to use the char [sizeof...(Params)] . This has the disadvantage that the compiler only passes a pointer to this array when you try to pass such an array as an argument. Therefore, it is better to use allocatorStruct<sizeof...(Params)> .
And now the main idea:
When saving a function, we can overlay it on: T (*)(allocatorStruct<sizeof...(Params)>) . When saving arguments for a function, we can save them in a struct of type allocatorStruct<sizeof...(Params)> .
The size of the arguments is the same. Although the function pointer is about the type of function, the specified function will return its data.
At least I was hoping. Depending on the calling convention, I expected that the arguments passed might be reordered or incorrect due to the difference between the save arguments from left to right and going from right to left. But that was not so. With __cdecl, only the first argument is called, and the other is lost. With other calling conventions, the program has stopped working.
I did not spend much time debugging and searching for data in memory (on the stack). Is this at least the right way?