处理未知容器中所有项目的最有效方法

Most efficient way to process all items in an unknown container?

本文关键字:项目 有效 方法 未知 处理      更新时间:2023-10-16

我在C++中进行计算,计算速度必须尽可能快(可能需要大量数据,每秒执行60次)。在计算过程中,必须处理一组特定的项目。然而,在不同的情况下,项目存储的不同实现是最佳的,所以我需要使用一个抽象类。

我的问题是,用C++中的每个项执行操作最常见、最有效的方法是什么?(在此期间,我不需要更改容器的结构。)我想到了两种可能的解决方案:

  1. 为存储类制作迭代器。(它们也是我的,所以我可以添加它。)这在Java中很常见,但对我来说不是很"C":

    class Iterator {
    public:
        bool more() const;
        Item * next();
    }
    
  2. 添加一种抽象处理程序,它将在计算部分被覆盖,并将包括对每个项目调用的代码:

    class Handler {
    public:
        virtual void process(Item &item) = 0;
    }
    

    (仅仅一个函数指针是不够的,因为它还必须带来一些其他数据。)

  3. 完全不同的东西?

第二种选择对我来说似乎有点好,因为事实上,项目可以在一个循环中处理而不会中断,但它会使代码变得非常混乱,因为我必须创建很多派生类。你有什么建议?

谢谢。

编辑:更准确地说,存储数据类型不仅仅是一个ADT,它只能根据一些参数只找到其中元素的特定子集,然后我需要处理这些参数,所以我不能在数组或其他东西中准备所有元素。

#include <algorithm>

看看C++标准提供的现有容器,以及for_each等函数。

要将C++容器迭代与"现代"语言中的接口进行比较,请参阅我的答案。其他答案有一些很好的例子,说明了惯用的C++方法在实践中是什么样子的。

与虚拟调度相比,使用模板化的函子(就像标准容器和算法一样)肯定会给您带来速度优势(尽管有时编译器可能会使调用失去机会,但不要指望它)。

C++已经有迭代器了。这不是一个特别"Java"的东西。(注意,它们的接口不同,而且它们比Java等价物效率高得多)

至于第二种方法,如果您担心吞吐量,那么为每个元素调用一个虚拟函数会影响性能。

如果您可以(预)对数据进行排序,以便连续存储相同类型的所有对象,那么您可以选择函数来调用一次,然后将其应用于该类型的所有元素。否则,您将不得不对虚拟函数或其他机制进行间接/类型检查,以对每个单独的元素执行适当的操作。

迭代器不是很像C++的印象是什么?标准库中充满了它们(见此),并包括一系列算法,这些算法可用于在各种标准容器类型上有效执行任务。

如果你使用STL容器,你可以省去重新发明轮子的麻烦,并轻松访问各种预定义的算法。这几乎总是比用特别的迭代解决方案编写自己的等效容器要好。

可能是一个函数模板:

template <typename C>
void process(C & c)
{
    typedef typename C::value_type type;
    for (type & x : c) { do_something_with(x); }
}

迭代将使用容器迭代器,这通常是尽可能高效的。

您可以针对特定容器专门化模板。