env->CallObjectMethod(hashMapInstance, put, _, _)
我想用下划线的
std::string
,int
和double
的所有可能排列来调用此函数。例如: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
只是一个可以容纳string
,int
和double
的类,以后可能还会更多)我想到的第一件事是创建一个模板化函数:
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(提示:使用递归)。