gpt4 book ai didi

c++ - 如何从 unique_ptr 的 vector 中获取派生迭代器?

转载 作者:行者123 更新时间:2023-11-28 00:31:39 24 4
gpt4 key购买 nike

我有一个基类 ( Container ),它在 Base 的 vector 中包含各种对象 ( std::unique_ptr<Base> 项)我有一个派生类 ( FolderOfFolders ),它只包含特定项目 ( Folder 项目)。我想使用 range-based-for 遍历该特定对象( FolderOfFolder ),但我不知道该怎么做。使用 range-based-for 我可以返回 std::unique_ptr<Base>项目,但我想要 const Folder*那些。我知道我需要一个 begin(), end() 对来为基于范围的 for 提供迭代器,但我需要一个来自 std::unique_ptr<Base> 的转换至 const Folder* .这有可能吗?

class Container : public Base {
public:
// I want to get back these as Folder* from FolderOfFolders
std::vector<std::unique_ptr<Base>> items;
};

class Folder : public Container {
public:
// I want to call this when I traverse FolderOfFolders with range-based-for
void folderMethod();
...
};

class SystemFolder : public Folder {
public:
...
};

class UserFolder : public Folder {
public:
...
};

class FolderOfFolders : public Folder {
public:

// I know that every item is a Folder in items
// can I get an iterator to a Folder* ?!
iterator begin() {
// ???
return items.begin();
}
iterator end() {
// ???
return items.end();
}
};

我想用它作为

FolderOfFolders folderOfFolders;
for (folder : folderOfFolders)
folder->folderMethod();

最佳答案

#include <boost/iterator/transform_iterator.hpp>

struct Downcast
{
typedef const Folder* result_type;

result_type operator()(const std::unique_ptr<Base>& p) const
{ return static_cast<const Folder*>(p.get()); }
};

class FolderOfFolders : public Folder {
public:

typedef boost::transform_iterator<Downcast, decltype(items)::iterator> iterator;

iterator begin() {
return iterator(items.begin(), Downcast());
}
iterator end() {
return iterator(items.end(), Downcast());
}
};

注意因为 FolderOfFolders::iterator::operator* 按值返回一个 const Folder*,这意味着 FolderOfFolders::iterator::reference 不是一个引用类型,因此迭代器只是一个 InputIterator,而不是像底层 vector::iterator 那样的 RandomAccessIterator,但这足以与基于范围的 for 一起使用。

然而,这种“一切都是Base,所有集合都是Base的集合”的说法有点像Java。有更好的设计。即使您必须存储 Base 的容器,您也可以这样做而不必更改迭代器类型:

const Folder& asFolder(const Base& b) {
return dynamic_cast<const Folder&>(b);
}

class FolderOfFolders : public Folder {
public:

typedef decltype(items)::iterator iterator;

iterator begin() {
return items.begin();
}
iterator end() {
return items.end();
}
};

...

for (auto& base_ptr : folderOfFolders)
asFolder(*base_ptr).folderMethod();

关于c++ - 如何从 unique_ptr<Base> 的 vector 中获取派生迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22696806/

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