gpt4 book ai didi

java - 将 SWIG 与 C++ 的 std::map 一起使用时,Java 没有迭代器

转载 作者:可可西里 更新时间:2023-11-01 17:37:22 26 4
gpt4 key购买 nike

我已经在 C++ 中使用 std::map 实现了一个类,并使用 SWIG 创建了可从 Java 调用的接口(interface)。但是,没有迭代器对象允许我迭代 SWIG 包装的 std::map 中的条目。有谁知道如何创建迭代器?

最佳答案

为了能够在 Java 中迭代一个对象,它需要实现 Iterable。这又需要一个名为 iterator() 的成员函数,它返回一个合适的 Iterator 实现。

从您的问题来看,您不清楚您在 map 中使用的是什么类型,以及您是否希望能够迭代对(就像在 C++ 中那样)、键或值。三个变体的解决方案基本相似,我在下面的示例中选择了值。

首先,我用来测试这个的 SWIG 接口(interface)文件的序言:

%module test

%include "std_string.i"
%include "std_map.i"

为了实现可迭代映射,我在 SWIG 接口(interface)文件中声明、定义和包装了另一个类。 MapIterator 这个类为我们实现了Iterator 接口(interface)。它是 Java 和封装 C++ 的混合体,其中一个比另一个更容易编写。首先是一些 Java,一个类型映射,它给出了它实现的接口(interface),然后是 Iterable 接口(interface)所需的三个方法中的两个,作为类型映射给出:

%typemap(javainterfaces) MapIterator "java.util.Iterator<String>"
%typemap(javacode) MapIterator %{
public void remove() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}

public String next() throws java.util.NoSuchElementException {
if (!hasNext()) {
throw new java.util.NoSuchElementException();
}

return nextImpl();
}
%}

然后我们提供 MapIterator 的 C++ 部分,它有一个私有(private)实现,除了 next() 的异常抛出部分和迭代器所需的状态(用 std::map 自己的 const_iterator 表示。

%javamethodmodifiers MapIterator::nextImpl "private";
%inline %{
struct MapIterator {
typedef std::map<int,std::string> map_t;
MapIterator(const map_t& m) : it(m.begin()), map(m) {}
bool hasNext() const {
return it != map.end();
}

const std::string& nextImpl() {
const std::pair<int,std::string>& ret = *it++;
return ret.second;
}
private:
map_t::const_iterator it;
const map_t& map;
};
%}

最后,我们需要告诉 SWIG 我们正在包装的 std::map 实现了 Iterable 接口(interface),并提供了一个额外的成员函数来包装 std::map 返回我们刚刚编写的 MapIterator 类的新实例:

%typemap(javainterfaces) std::map<int,std::string> "Iterable<String>"

%newobject std::map<int,std::string>::iterator() const;
%extend std::map<int,std::string> {
MapIterator *iterator() const {
return new MapIterator(*$self);
}
}

%template(MyMap) std::map<int,std::string>;

这可能更通用,例如使用宏来隐藏 map 的类型,这样如果您有多个 map ,这只是一个为适当的 map “调用”宏的问题,就像您使用 %模板

原始类型的映射也有一点复杂 - 您需要安排 Java 端使用 Double/Integer 而不是 double/int(我认为是自动装箱这个术语),除非你决定已经包装成对,在这种情况下你可以与原始成员成对。

关于java - 将 SWIG 与 C++ 的 std::map 一起使用时,Java 没有迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9465856/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com