我正在尝试为函数/类方法编写一个通用包装器(用于某些脚本解释器),它将所有调用参数从字符串转换为某种任意类型 T。 我将尝试分点涵盖主题:
- 脚本允许映射用户功能
- 当解释器试图处理用户函数时——创建一个回调例程
- 回调旨在获取描述(一个接一个)参数值的对象数组
- 我已经有了将字符串转换为任意(基本)类型 T 的(模板)例程
- 我想包装用户例程(外部提供为可变 std::function<> 类型),以便自动完成从回调数组的后续字符串到适当参数的转换
例子:
回调例程原型(prototype)如下:
int CallbackFn(Interp *interp, int argc, const char **argv)
我得到了(样本)用户函数:
int UserRoutine(const std::string &in_str, int x);
所以 std::function 看起来像:
std::function<int(const std::string&, int)>
通用转换例程的语法为:
template <typename T>
T conv(const char *str);
我有转换的专长:
- “const char*”到“std::string”
- “const char*”到“int”
这样理想的转换看起来像:
std::string p0 = conv<std::string>(argv[0]);
int p1 = conv<int>(argv[1]);
它可以全部包装到可变参数模板中,但 std::function<...> 参数与我正在准备的类型不完全匹配 - 例如将对象作为常量 T& 传递是很常见的,而我需要创建“纯”类型的 T。
有什么想法可以处理不同的参数传递方式吗?
最佳答案
老实说,第一个问题是您正在重新发明轮子。默认转换函数为operator>> (istream&, T&)
.将每个参数填充到 std::stringstream
中.显然,operator<<
返回类型。
正如您正确注意到的那样,您使用了可变参数模板。但我不会费心生成 std::function<int(const std::string&, int)>
这里。相反,您总是生成通用类型 std::function<std::string(std::string)>
.每个打包函数都包含正确的参数转换。
这给了我们声明
template<typename RET, typename Args...>
std::function<std::string(std::string) (RET (*fptr)(Args...));
body 大概要长得大致像
std::tuple<Args...> args;
std::istringstream iss(fromScript);
iss>>args;
std::ostringstream oss;
oss << *fptr(args.get<0>, args.get<1>(), ...);
return oss.str();
对于 *fptr
的棘手调用, 请参阅 C++11: I can go from multiple args to tuple, but can I go from tuple to multiple args?
[编辑]
我只是注意到我错过了一点:“参数与我正在准备的类型不完全匹配——例如,将对象作为 const T&
传递是很常见的,而我需要创建 T
的“纯”类型。”。我怀疑你在找 std::decay<Arg>
.
关于c++ - 如何为泛型 std::function 的参数声明 "basic"类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49451248/