Question

I am taking a structure that contains variadic types, extracting them, and passing them to a native function call.

//ValueArray contains a vector of a variant type.

// Pulls out an argument from a ValueArray.
template<typename Arg>
inline Arg
_processParam( ValueArray& args ) {
    Arg arg = static_cast<Arg&>( args[ 0 ] );
    args.erase( 0, true );
    return arg;
}


/// Do the Function call. Args is a variadic template pack.
call( fnPtr, _processParam<Args>( args )... );

/// The call expands to:
(*fnPtr)( params... );

The problem however is that the _processParam( args )... expansion is pulling out the args by type in reverse order. For example, a ValueArray of [ 1, 1.4 ] will be pulled out as a double, then and int. Is there a way to pull out the arguments correctly and in a portable way?

Was it helpful?

Solution

Get rid of the erase and add an index. Do not mutate data used in other parameter calculations when making a function call, as the order is undefined (which lets the compiler reorder them for efficiencies sake, or the phase of the miin).

You will need to add one level of indirection to do this easily:

template<unsigned...>struct indexes {};

template<unsigned num, unsigned... Is>struct make_indexes:
  make_indexes<num-1, num-1, Is...>{};
template<unsigned...Is>struct make_indexes<0,Is...>:indexes<Is...>{};

template<typename... Args, unsigned...Is>
void do_call(indexes<Is...>, ValArray& arr){
  call( fnPtr, ProcessParam<Args>( arr[Is] )... );
}

where ProcessParam now takes an element not an array, and use it like:

do_call<Args...>( make_indexes<sizeof...(Args)>(), arr );
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top