- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个基类 ( 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/
我是一名优秀的程序员,十分优秀!