我试图为函数/类方法编写一个通用包装器(对于某些脚本解释器),它将所有调用参数从字符串转换为某种任意类型T. 我将尝试用以下几点来讨论主题:
示例:
回调例程的原型如下:
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);
我有专业化转换:
因此理想情况下转换看起来像:
std::string p0 = conv<std::string>(argv[0]);
int p1 = conv<int>(argv[1]);
它可以包装成可变参数模板,但是std :: function&lt; ...&gt;参数与我准备的类型不完全匹配 - 例如将对象作为const T&amp;传递是很常见的,而我需要创建&#34; pure&#34; T的类型。
如何处理传递参数的不同方法?
答案 0 :(得分:4)
第一个问题是你要重新发明轮子,说实话。默认转换功能为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...));
身体大致必须看起来像
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&
传递是很常见的,而我需要创建”纯“类型的{{1} }“。我怀疑你正在寻找std::decay<Arg>
。