The code below "seems" to work - however, I'm a little concerned that I'm in the realms of unspecified behaviour at the marked point. If I am, can someone please throw me a bone so that I can ensure that I'm not going to have it suddenly break when I change compiler?
The intent (in case it isn't clear) is that I want to generate a std::function that is able to wrap another - but process the arguments in a slightly different way.
/// Some collection of arguments generated at runtime.
class ArgCollection
{
int argCount;
std::variant *arguments;
}
/// generate the wrapping fn
template<class ...Args>
std::function<void(ArgCollection)> GetConvert(std::function<void(Args...)> thing)
{
constexpr std::size_t argCount = sizeof...(Args);
return [argCount, method](const ArgCollection& args) -> void {
if (args.numArguments != argCount)
throw std::invalid_argument("Invalid number of arguments");
int count = 0; <------------ I fear about the usage of this variable.
auto convertedArgs = std::make_tuple(ConvertArg<Args>(args, count++)...);
std::apply(method, convertedArgs);
};
}
/// helper const & reference stripping
template<typename T>
using base_type = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
/// Get the idx'th argument, and convert it to what we can hand to the function
template<class T>
static base_type<T> ConvertArg(const ArgCollection &args, int idx)
{
return base_type<T>(args[idx]);
}