c++ - 一个 C++ 迭代器适配器,它包装和隐藏内部迭代器并转换迭代类型

标签 c++ templates iterator wrapper adapter

玩弄了这个,我怀疑这是不可能的,但我想我会问专家。我有以下 C++ 代码:

class IInterface
{
    virtual void SomeMethod() = 0;
};

class Object
{
    IInterface* GetInterface() { ... }
};

class Container
{
private:
    struct Item
    {
        Object* pObject;
        [... other members ...]
    };
    std::list<Item> m_items;
};

我想将这些方法添加到 Container 中:

    MagicIterator<IInterface*> Begin();
    MagicIterator<IInterface*> End();

为了让调用者可以写:

Container c = [...]
for (MagicIterator<IInterface*> i = c.Begin(); i != c.End(); i++)
{
    IInterface* pItf = *i;
    [...]
}

所以本质上我想提供一个类,它似乎在迭代 IInterface 指针的某些集合(不允许 Begin() 和 End() 的调用者看到),但实际上是在迭代指向可以转换为 IInterface 指针的其他对象(Container 类私有(private))的指针。

几个关键点:

  • MagicIterator将在 Container 之外定义.
  • Container::Item必须保持私密。
  • MagicIterator必须遍历 IInterface指针,尽管 Container持有 std::list<Container::Item> . Container::Item包含 Object* , 和 Object可用于获取 IInterface* .
  • MagicIterator必须可与多个类似于 Container 的类重用,但可能在内部具有不同的列表实现,包含不同的对象( std::vector<SomeOtherItem>mylist<YetAnotherItem> )和 IInterface*每次都以不同的方式获得。
  • MagicIterator不应该包含容器特定的代码,尽管它可以委托(delegate)给有的类,前提是这种委托(delegate)没有硬编码到 MagicIterator 内的特定容器。 (例如,编译器会以某种方式自动解决)。
  • 该解决方案必须在 Visual C++ 下编译,不得使用其他库(例如 boost),这需要其作者的许可协议(protocol)。
  • 此外,迭代可能不会分配任何堆内存(因此在任何阶段都不会分配 new()malloc()),也不会分配 memcpy() .

感谢您的宝贵时间,即使您只是在阅读;这个真的烦死我了!

更新:虽然我得到了一些非常有趣的答案,但还没有一个满足上述所有要求。值得注意的是,棘手的领域是 i) 以某种方式将 MagicIterator 从 Container 中解耦(默认模板参数不会削减它),以及 ii) 避免堆分配;但我真的在寻求涵盖上述所有项目符号的解决方案。

最佳答案

我认为您在这里有两个不同的问题:

首先,创建一个返回 IInterface* 的迭代器。来自您的list<Container::Item> .这很容易通过 boost::iterator_adaptor 完成。 :

class cont_iter
  : public boost::iterator_adaptor<
        cont_iter                       // Derived
      , std::list<Container::Item>::iterator // Base
      , IInterface*                     // Value
      , boost::forward_traversal_tag    // CategoryOrTraversal
      , IInterface*                     // Reference :)
    >
{
 public:
    cont_iter()
      : cont_iter::iterator_adaptor_() {}

    explicit cont_iter(const cont_iter::iterator_adaptor_::base_type& p)
      : cont_iter::iterator_adaptor_(p) {}

 private:
    friend class boost::iterator_core_access;
    IInterface* dereference() { return this->base()->pObject->GetInterface(); }
};

您可以在 Container 中将此类型创建为内部类型。并从其 begin() 返回和 end()方法。

其次,您需要运行时多态 MagicIterator .这正是any_iterator做。 MagicIterator<IInterface*>只是 any_iterator<IInterface*, boost::forward_traversal_tag, IInterface*> , 和 cont_iter可以只分配给它。

关于c++ - 一个 C++ 迭代器适配器,它包装和隐藏内部迭代器并转换迭代类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/470835/

相关文章:

c++ - 为什么我在 QtCreator 中收到 undefined reference 错误?

c++ - 如何在 Cygwin 中运行多个参数

c++ - `std::nullptr_t` 类型的用途是什么?

javascript - Grails如何让AJAX发送从模板表单中编辑的对象

c++ - 错误 : aggregate ‘food_type a’ has incomplete type and cannot be defined

arrays - Julia : Cartesian product of multiple arrays

c++ - 从字符指针获取迭代器 (C++)

c++ - const 引用是错误的 C++ 11

c++ - 为什么 VS 2008 编译时没有带有错误模板逻辑的警告?

自定义模板类的 C++ 迭代器