我想知道,鑒于以下約束條件,是否有可能使用變數函式/模板,以便將可變數量的引數(這些引數本身就是一個函式的回傳值)傳遞到一個變數函式。
限制條件:
簡短的例子:
using fn = F(...)。
fn* func = (fn*) addr;
value = (*func)(pop_t(outputstack,o_stackidx,o_stacksize) ...)。
push_t(outputstack,o_stackidx,o_stacksize, value)。
fn*是一個函式指標(從一個已知的用戶定義的函式記憶體地址轉換而來),它接收了一個數量可變的pop_t引數(從堆疊中彈出的值),這些值(outputstack,o_stackidx,o_stacksize)是靜態的,本身不需要是可變的。 本質上,我想知道是否有可能讓 pop_t 函式重復一個可變的次數,A.)取決于 fn 能夠接受的適當數量的引數,或者 B.)使用一個用戶定義的整數來指定重復次數。
作為一個例子,假設用戶要輸入一個 sin 或 atan2 函式,這兩個函式分別接受不同數量的引數 sin(x) 和 atan(y,x) 。對于這兩個各自的函式,函式呼叫運算式將如下:
sin -> (*func)(pop_t(outputstack,o_stackidx,o_stacksize))。
atan2 -> (*func)(pop_t(outputstack,o_stackidx,o_stacksize),pop_t(outputstack,o_stackidx,o_stacksize))。
有N個引數的函式通過呼叫pop_tN次從堆疊中彈出N個值。
可重復的例子:
template<class U, class I>
U pop_t(U* stack, I &stackidx, I & stacksize){
if(stacksize>0){
stacksize--;
stackidx = stackidx--。
return stack[stackidx]。
}
else {
return stack[stackidx]。
}
}
int main() {
float outputstack[2] = {3.141/2,1};
int o_stackidx = 2;
int o_stacksize = 2;
long addr = (long)&atan2;
using fn = float(...) 。
fn* func = (fn*) addr;
//未知變數的函式指標。
float value = (*func)(pop_t(outputstack,o_stackidx,o_stacksize,nt) ...)。
return 0。
uj5u.com熱心網友回復:
看來你想根據引數的數量來多次重復一個陳述句,在這種情況下,你可以利用C 模板的幫助:
然后你可以這樣使用:
repeat_for_args(some_function, [&] () {
(*func)(pop_t(outputstack,o_stackidx,o_stacksize))
});
如果你想自己先嘗試一下:
編輯 1:1:1
編輯1:要在模板的幫助下生成一個引數中帶有 首先,你需要定義這個輔助類:N重復型別的函式指標型別,你可以這么做:
#include <tuple>
template <typename, typename>
struct make_sig_from_tuple。
template <typename R, typename ...Args>
struct make_sig_from_tuple<R, std::tuple<Args...> > {
using type = R(*)(Args...) 。
};
template <typename R, typename ...Args>
using make_sig_from_tuple_t = typename make_sig_from_tuple<R, Args...> :type;
然后我們可以這樣做,
template <typename T, size_t N>
struct generate_sig_impl {
using type = decltype(std::tuple_cat(std::declval< std:: tuple<T>&>(), std::declval<typename generate_sig_impl<T, N - 1>:type&>()) 。)
};
template <typename T>
struct generate_sig_impl<T, 0> {
using type = std::tuple<> 。
};
template <typename R, typename T, size_t N>
struct generate_sig {
using type = make_sig_from_tuple_t<R, typename generate_sig_impl<T, N>:type> 。
};
template <typename R, typename T, size_t N>
using generate_sig_t = typename generate_sig<R, T, N> ::type;
現在可以用它來鑄造變數函式,只用N的值,而不必在型別中多次明確說明引數:
repeat_for_args(reinterpret_cast<generate_sig_t< float, float, 3>>(function_with_variadic_arguments), /* . .. */)。)
//等同于: repeat_for_args(reinterpret_cast<float(*)(float, float, float)>(function_with_variadic_arguments) , /* ... */);
編輯2:由于評論中的OP希望將引數的順序也顛倒過來,我們可以這樣做:
template <typename Arg1, typename ...Args>。
struct reverse_func_sig_impl {
using type = decltype(std::tuple_cat(std::declval<typename reverse_func_sig_impl< Args. ...>::type&>(), std::declval<std::tuple<Arg1>&>())。
};
template <typename Arg1>
struct reverse_func_sig_impl< Arg1> {
using type = std::tuple<Arg1> 。
};
template<typename>
struct reverse_func_sig;
template <typename R, typename... Args>
struct reverse_func_sig<R(Args...) > {
using type = make_sig_from_tuple_t<R, typename reverse_func_sig_impl<Args...> :type> 。
};
template <typename FuncPtr>
using reverse_func_sig_t = typename reverse_func_sig<FuncPtr>:type。
然后像這樣使用它:
repeat_for_args(reinterpret_cast<generate_sig_t< int(float, int)>>(function_with_variadic_arguments), /* . .. */)。)
//等同于: repeat_for_args(reinterpret_cast<int(int, float)>(function_with_variadic_arguments) , /* ... */);
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/314151.html
標籤:
上一篇:嘗試多載<<運算子時出錯
下一篇:C 有兩個以上型別的條件型定義
