我的问题在以下代码中:
template <class _type>
_type translateArgument (std::string);
template <class _type>
std::string translateResult (_type result);
template <class _function_type, _function_type _function, class _result_type, class... _arguments_type>
struct Function
{
typedef std::tuple<_arguments_type...> arguments_type;
static void call(std::stack<std::string> stack)
{
auto value1 = translateArgument<std::tuple_element<0, arguments_type>::type>(stack.top());
stack.pop();
auto value2 = translateArgument<std::tuple_element<1, arguments_type>::type>(stack.top());
stack.pop();
...
}
};
1.第一个问题:
如何从value1到valueN生成代码,其中N是sizeof ...(_ arguments_type)
2.第二个问题:
如果_result_type为void,则将代码添加到Function :: call
的末尾_function(value1, value2, ...);
否则,将代码添加到Function :: call
的末尾stack.push(translateResult<_result_type>(_function(valu1, value2, ...)));
答案 0 :(得分:1)
template <typename F, F function, typename R, typename... Args>
struct Function
{
using arguments_type = std::tuple<Args...>;
static void call(std::stack<std::string>& stack)
{
call_n(std::is_void<R>{}, stack, std::index_sequence_for<Args...>{});
}
template <std::size_t I>
static typename std::tuple_element<I, arguments_type>::type f(std::stack<std::string>& stack)
{
typename std::tuple_element<I, arguments_type>::type e{ translateArgument<typename std::tuple_element<I, arguments_type>::type>(stack.top()) };
stack.pop();
return e;
}
template <std::size_t... Is>
static void call_n(std::true_type, std::stack<std::string>& stack, std::index_sequence<Is...>)
{
std::tuple<Args...> tpl{ f<Is>(stack)... };
function(std::get<Is>(std::move(tpl))...);
}
template <std::size_t... Is>
static void call_n(std::false_type, std::stack<std::string>& stack, std::index_sequence<Is...>)
{
std::tuple<Args...> tpl{ f<Is>(stack)... };
stack.push(processResult(function(std::get<Is>(std::move(tpl))...)));
}
};
答案 1 :(得分:1)
以下代码使用indices trick两次以便:
代码使用C ++ 14中的std::integer_sequence
,但如果需要,可以很容易地将其转换为C ++ 11。
#include <iostream>
#include <stack>
#include <utility>
#include <string>
using Stack = std::stack<std::string>;
template <typename Type>
Type translate_argument(const std::string&);
template<>
int translate_argument<int>(const std::string& str)
{
return std::stoi(str);
}
template <typename Type>
Type translate_arg(Stack& stack)
{
Type value = translate_argument<Type>(stack.top());
stack.pop();
return value;
}
template <typename Type>
std::string translate_result(const Type& result)
{
return std::to_string(result);
}
template <typename Tuple, std::size_t... Indices>
Tuple call_translate_arg_detail(Stack& stack, Tuple, std::index_sequence<Indices...>)
{
return Tuple{translate_arg<typename std::tuple_element<Indices, Tuple>::type>(stack)...};
}
template <typename... Args>
std::tuple<Args...>
call_translate_arg(Stack& stack)
{
return call_translate_arg_detail(stack,
std::tuple<Args...>{},
std::index_sequence_for<Args...>{}
);
}
template <typename Tuple, size_t... Indices, typename Ret, typename... Args>
Ret
call_fun_detail(Tuple& tuple, Ret(*fun)(Args...), std::index_sequence<Indices...>)
{
return fun(std::get<Indices>(tuple)...);
}
template <typename Tuple, typename Ret, typename... Args>
Ret
call_fun(Tuple& tuple, Ret(*fun)(Args...))
{
return call_fun_detail(tuple,
fun,
std::make_index_sequence<std::tuple_size<Tuple>::value>{}
);
}
template <typename Signature, Signature function>
struct Function;
template <typename Ret, typename... Args, Ret(*fun)(Args...)>
struct Function<Ret(Args...), fun>
{
static void call(Stack& stack)
{
auto arg_tuple = call_translate_arg<Args...>(stack);
Ret result = call_fun(arg_tuple, fun);
stack.push(translate_result(result));
}
};
// specialization for void return value
template <typename... Args, void(*fun)(Args...)>
struct Function<void(Args...), fun>
{
static void call(Stack& stack)
{
auto arg_tuple = call_translate_arg<Args...>(stack);
call_fun(arg_tuple, fun);
}
};
<强>演示:强>
void foo(int x, int y)
{
std::cout << "foo: x=" << x << " y=" << y << std::endl;
}
int bar(int x, int y, int z)
{
int result = x+y+z;
std::cout << "bar: x=" << x << " y=" << y << " z=" << z << std::endl;
std::cout << "bar: result=" << result << std::endl;
return result;
}
int main()
{
Stack stack;
stack.push("10");
stack.push("20");
stack.push("30");
Function<decltype(bar), bar> bar_fun;
bar_fun.call(stack);
stack.push("100");
Function<decltype(foo), foo> foo_fun;
foo_fun.call(stack);
return 0;
}
<强>输出:强>
bar: x=30 y=20 z=10
bar: result=60
foo: x=100 y=60