env->CallObjectMethod(hashMapInstance, put, _, _)

我想用下划线的std::stringintdouble的所有可能排列来调用此函数。例如:
env->CallObjectMethod(hashMapInstance, put, myString, myInt)
env->CallObjectMethod(hashMapInstance, put, myInt, myDouble)
env->CallObjectMethod(hashMapInstance, put, myInt, myInt)
//...

当然,我可以使用嵌套的ifs来做到这一点,但是我会在很多地方重用相同的代码。理想情况下,我想要一种接收std::map<JavaObject, JavaObject> myMap的方法,然后对 map 上的每一对都执行以下操作:
for (auto pair : myMap)
    if (pair.first.type == JavaObject::String && pair.second.type == JavaObject::Integer)
        env->CallObjectMethod(hashMapInstance, put, pair.first.getString(), pair.second.getInt())
    //OR
    if (pair.first.type == JavaObject::Integer && pair.second.type == JavaObject::Integer)
        env->CallObjectMethod(hashMapInstance, put, pair.first.getInt(), pair.second.getInt()) //
    //OR
    if (pair.first.type == JavaObject::Double && pair.second.type == JavaObject::String)
        env->CallObjectMethod(hashMapInstance, put, pair.first.getDouble(), pair.second.getString())
    //...

如您所见,我需要一种方法,能够针对收到的env->CallObjectMethod(hashMapInstance, put, _, _)的每个可能排列有效地调用每个排列JavaObject, JavaObject(JavaObject只是一个可以容纳stringintdouble的类,以后可能还会更多)

我想到的第一件事是创建一个模板化函数:
template<typename T, typename V>
void myCallobjectMethod(env, jobject instance, jmethodID method, T obj1, V obj2)

但是我仍然必须先阅读JavaObject.type,然后在if中阅读,如果是第二部分,则再阅读ojit_code,只是调用我的模板化函数,所以我仍然遇到相同的问题。

我想到了另一种方式,用伪代码:
using namespace std::placeholders;
for (auto pair : myMap)
    auto bind1 = std::bind(env->CallObjectMethod, hashMapInstance, put, _3, _4); //binds the hashMapInstance and put
    auto bind2 = std::bind(bind1, pair.first, _2); //binds the first object
    auto bind3 = std::bind(bin2, pair.second); //binds the second object
bind3(); //now I can call bind3 to execute the call

但这不是那么简单,我什至不知道这里的事物类型正在发生什么。

最佳答案

JavaObject是求和类型,因此应具有visit函数:

template<class F> auto visit(F&& f, JavaObject const& o) {
    switch (o.type) {
        case JavaObject::String : return f(o.getString());
        case JavaObject::Integer : return f(o.getInt());
        case JavaObject::Double : return f(o.getDouble());
    }
}

任何一元visit函数都可以与其自身组合以对2个参数进行操作:
template<class F> auto visit(F&& f, JavaObject const& o1, JavaObject const& o2) {
    return visit([&](auto const& x1) {
        return visit([&](auto const& x2) {
            return f(x1, x2); }, o2); }, o1);
}

现在您可以编写:
visit([&](auto const& x1, auto const& x2) {
    env->CallObjectMethod(hashMapInstance, put, x1, x2);
}, pair.first, pair.second);

读者可以自己练习将visit扩展为任意Arity(提示:使用递归)。

07-24 09:34