java如何编写以通用方式接受迭代器或集合的函数?
我过去8年来一直是java程序员,最近我一直在玩C++。这是我在C++ STL和java中遇到的一个问题,p>在Java中,您可以编写一个采用迭代器的方法,如下所示:
void someMethod(Iterator<String> data) {
// ...
}
传入一个Iterator
,该方法不需要知道该迭代器的底层集合是什么,这很好
void some_function(std::vector<std::string>::const_iterator data) {
// ...
}
换句话说,some_function
知道迭代器是vector
上的迭代器。这并不好,因为我希望函数能够工作,而不管迭代器的底层集合是什么
附录
谢谢你的回答。除了答案之外,我在Nicolai M.Josuttis的书The C++ Standard Library: A Tutorial and Reference的第7.5段(迭代器特征)中找到了一些关于这方面的好信息。第7.5.1段解释了如何为不同迭代器类别编写函数的专用版本
# 1 楼答案
最好通过命名约定指出迭代器的类型,以及迭代器需要拥有的属性类型。下面是迭代器的一些常见命名约定:
下面是序列类型容器的通用定义,其中包括vector和deque
# 2 楼答案
可以使用header file 并指定迭代器必须支持的最低要求
因此,在上面的示例中,您可能希望将函数重写为:
对于要求只能在集合中向前移动迭代器(++)的内容
# 3 楼答案
你可能想考虑函数模板。看看一些}函数模板是如何工作的,比如
std
{std::for_each
例如
然后,您可以使用多种iterable范围调用从该模板生成的函数
例如
# 4 楼答案
这是C++和java之间的一个很大的区别。Java唯一的抽象工具是运行时多态性(接口和抽象类)。在C++中,你不限于此。可以为类型创建别名,并让类具有其他关联/嵌套类型。在很多情况下,它可以让你不受运行时多发性的影响。编译时类泛型的优点是速度非常快(没有虚拟函数调用,也没有内联的可能性)。此外,当你没有垃圾收集器时,它还简化了生活管理。只需在堆栈上创建对象即可
下面是一个(未经测试的)示例:
在这里,“Iter”只是一个名字。它实际上没有对类型施加任何约束。如果你想用一个不是迭代器的类型(至少在结构上)实例化这个模板,你会得到一个编译时错误(编译时duck类型)。所以,你工作的一部分是记录你期望的类型。这通常是通过选择模板参数(即ForwardIterator)和注释的一些描述性名称来实现的
我还应该提到的是,如果您将这个函数模板与各种迭代器一起使用,那么多个“sum”函数将被“实例化”。如果你不想要这种代码复制和/或真的需要运行时多态性,你可以应用一种叫做“类型擦除”的技术。不过,迭代器的类型擦除不是标准库的一部分。而且,我从未觉得有必要将这种技术应用于迭代器。但是在其他库中,比如boost::any和boost::function中,您会发现类型擦除的用法
您还可以使用其他一些模板技巧来区分不同的迭代器类别(请参见“标记分派”)或约束函数模板(请参见“SFINAE”)。如果您对类型删除感兴趣,请尝试Google C++,类型擦除,迭代器。基本上可以创建一个句柄类(通过指针)来管理多态对象。这个多态对象包装了另一个你想“擦除”(隐藏)其类型的对象