2016-03-25 3 views
0

Примем следующие шаблоны:VARIADIC шаблон расширения индексируется пакет

template<typename T, bool stack> 
struct bind_argument 
{ 
    static inline T get_arg(Object& obj, u8 index) 
    { 
     return ...; 
    } 
}; 

template<typename RT, typename Arg0, typename... Args> 
inline RT call(Object& obj, RT(*function)(Arg0, Args...)) 
{ 
    constexpr bool use_stack = ...; 
    return function(..., bind_argument<Args, use_stack>::get_arg(obj, 0)...); 
} 

Для bind_argument Мне нужно передать индекс расширения. Another question относительно индексированного расширения продемонстрировал использование «трюков индексов» с использованием другого шаблона, но в моем случае мне также нужно передать расширенные аргументы вызову функции в вызове . Кажется, это немного сложнее, чем я думал.

Мое первоначальное решение с помощью "indices trick" выглядел следующим образом:

template<bool stack, typename... Args, u64... Indices> 
struct bind_arguments 
{ 
    static inline Args get_args(CPU& cpu, indices<Indices...>) 
    { 
     return bind_argument<Args, stack>(cpu, Indices)...; 
    } 
}; 

template<typename RT, typename Arg0, typename... Args> 
inline RT call(Object& obj, RT(*function)(Arg0, Args...)) 
{ 
    constexpr bool use_stack = ...; 
    Arg0 some_value = ...; 
    return function(some_value, bind_arguments<use_stack, Args...>::get_args(obj, build_indices<sizeof...(Args)>{})); 
} 

К сожалению, это не будет компилировать. Как можно выполнить расширение индексированного пакета шаблона внутри другого шаблона и после этого передать расширенные значения в место, предназначенное для расширенных значений? (В этом случае функции() вызов)

Расширение намеченной вызов будет выглядеть следующим образом:

function(some_value, bind_argument<A1, use_stack>(obj, 0), bind_argument<A2, use_stack>(obj, 1), bind_argument<A3, use_stack>(obj, 2), ...) 
+0

Я не понимание вопроса. Можете ли вы привести пример того, как должен выглядеть расширенный вызов (например, что «вызов » будет расширяться до?) –

+0

@ T.C. вы взяли слова прямо изо рта. Я * думаю * он хочет построить объект, содержащий кортежи (arg, index) ... который для меня просто звучит как 'tuple()' или 'std :: forward_as_tuple()'? –

+0

Я добавил пример нефинального расширения. Использование для эмулятора, которому нужно вызвать функции HLE с различными аргументами (первый аргумент всегда один и тот же, таким образом Arg0). Функция bind_argument принимает аргументы из регистров (или стека) и переводит их в нужный тип. Этот вопрос является некоторым продолжением моего [предыдущего вопроса] (https://stackoverflow.com/questions/36217632/using-n-arguments-from-args-starting-from-position-m). – tambre

ответ

1

Вы можете делать все, что вы хотите в этой другой функции, передавая все необходимые аргументы; нет никаких оснований для возвращения ничего, но конечный результат:

#include <utility> 
#include <cstddef> 

template <typename RT, typename Arg0, typename... Args, std::size_t... Is> 
inline RT call(Object& obj, RT(*function)(Arg0, Args...), std::index_sequence<Is...>) 
{ 
    return function(&obj, bind_argument<Args>::get_arg(obj, Is)...); 
} 

template <typename RT, typename Arg0, typename... Args> 
inline RT call(Object& obj, RT(*function)(Arg0, Args...)) 
{ 
    return call(obj, function, std::make_index_sequence<sizeof...(Args)>{}); 
} 

DEMO

Смежные вопросы