我想以一种任意函数
的方式生成包装器R func(A a, B b, ...)
的
std::function<std::string (std::vector<std::string>)>
返回,它包装f
,以便从向量中获取参数并使用boost::lexical_cast
进行(尝试)转换,返回值相同。
例如:
int add(int a, int b);
auto f = magic_wrap(&add);
auto result = f(std::vector<std::string>{"2", "3"});
// result == "5"
我的直觉告诉我应该可以使用可变参数模板,但我仍然坚持获取函数的返回和参数类型。这可能是某种方式,如果是这样,怎么样?
答案 0 :(得分:5)
我不了解boost::lexical_cast
,但我认为这应该有效:
template<std::size_t... Is>
struct index_sequence
{ };
template<std::size_t N, std::size_t... Is>
struct make_index_sequence : make_index_sequence<N - 1, N - 1, Is...>
{ };
template<std::size_t... Is>
struct make_index_sequence<0, Is...> : index_sequence<Is...>
{ };
template<typename R, typename... Args>
class wrapped
{
public:
explicit
wrapped(R (&func)(Args...))
: func_(func)
{
}
public:
std::string operator()(std::vector<std::string> args)
{
if (sizeof...(Args) != args.size()) {
throw std::logic_error("Incorrect number of arguments");
}
auto const& result = invoke(make_index_sequence<sizeof...(Args)>(),
args);
return boost::lexical_cast<std::string>(result);
}
private:
template<std::size_t... Is>
R invoke(index_sequence<Is...>, std::vector<std::string> const& args)
{
return func_(boost::lexical_cast<Args>(args[Is])...);
}
private:
R (*func_)(Args...);
};
template<typename R, typename... Args>
std::function<std::string (std::vector<std::string>)>
wrap(R (&func)(Args...))
{
return wrapped<R, Args...>(func);
}
您可以看到稍微修改过的版本的工作演示(不使用Boost的版本)here。