代码之家  ›  专栏  ›  技术社区  ›  Jack

在lambda中使用模板参数

  •  0
  • Jack  · 技术社区  · 9 年前

    我正在开发一种简单语言的函数图,一切都很好,但我想提供一种更好的方法来定义数值运算符,以更简洁的方式处理数值。

    主要问题是我有一些类似的东西:

    using BinaryFunction = std::function<StackValue(StackValue,StackValue)>;
    
    registerFunction("+", Type::FLOAT, {Type::FLOAT, Type::FLOAT}, BinaryFunction([](StackValue v1, StackValue v2) { return StackValue(v1.as<float>() + v2.as<float>()); }));
    registerFunction("+", Type::FLOAT, {Type::FLOAT, Type::INT}, BinaryFunction([](StackValue v1, StackValue v2) { return StackValue(v1.as<float>() + v2.as<s32>()); }));
    ..
    

    因此,基本上对于支持这两种功能的每个运算符 float int 数据类型我必须提供4种功能,这些功能可以与可能的组合一起使用

    int, int -> int
    int, float -> float
    float, int -> float
    float, float -> float
    

    现在我不想提供隐式类型转换,所以我可以为每个组合使用4个不同的函数,但我希望有一种方法一次性定义它们,而不必重复代码。

    问题是我如何做到这一点,主要问题在于lambda:

    [](StackValue v1, StackValue v2) { return StackValue(v1.as<float>() + v2.as<float>()); };
    

    为了能够做我需要的事情,我需要一种用模板参数化代码的方法,比如

    return StackValue(v1.as<T1>() + v2.as<T2>())
    

    然后正确的专业化 StackValue<T>(T) 剩下的就交给我吧。

    这样我就可以

    registerNumericFunction(...)
    {
      registerTemplate<float, float>(...);
      registerTemplate<s32, float>(...);
      ..
    }
    

    但我没有找到一个聪明的方法,因为我需要将lambda传递给应该是参数化的方法。我不知道这是否可能。

    1 回复  |  直到 9 年前
        1
  •  2
  •   Barry    9 年前

    你的意思是这样吗?

    template <typename T1, typename T2>
    void registerTemplate() {
        registerFunction("+", Type::FLOAT, {Type::FLOAT, Type::FLOAT},
                         BinaryFunction([](StackValue v1, StackValue v2) {
                             return StackValue(v1.as<T1>() + v2.as<T2>());
                         }));
    }
    
    registerTemplate<float, float>();
    registerTemplate<s32, float>();
    

    还是这个?

    template <typename T1, typename T2, typename Op>
    BinaryFunction makeFunction(Op op) {
        return [op](StackValue v1, StackValue v2) {
            return StackValue(op(v1.as<T1>(), v1.as<T2>()));
        };
    }
    

    用作:

    registerFunction("+", ..., makeFunction<float, float>(std::plus<>{}));
    registerFunction("+", ..., makeFunction<s32, float>(std::plus<>{}));
    

    如果你真的在你的问题中说清楚你想要完成什么,这将非常有帮助。