首页 文章

如何为泛型std :: function的参数声明“basic”类型

提问于
浏览
4

我正在尝试为函数/类方法编写一个通用包装器(对于某些脚本解释器),它将所有调用参数从字符串转换为某种任意类型T.我将尝试用点来覆盖主题:

  • 脚本允许映射用户功能

  • 当解释器尝试处理用户功能时 - 进行回调例程

  • 回调旨在获取描述(逐个)参数值的对象数组

  • 我已经有了(模板)例程,它将字符串转换为任意(基本)类型T.

  • 我想包装用户例程(外部提供为variadic std :: function <>类型),以便从后续字符串从回调数组到适当参数的转换自动完成

例:

回调例程的原型如下:

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 <...>参数与我正在准备的类型不完全匹配 - 例如将对象作为const T&传递是很常见的,而我需要创建“纯”类型的T.

任何想法如何处理传递参数的不同方法?

1 回答

  • 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& 非常常见,而我需要创建"pure"类型的 T . ” . 我怀疑你在寻找std::decay<Arg> .

相关问题