【发布时间】:2012-07-23 14:01:57
【问题描述】:
我需要存储 Base 类型以及派生类型 BaseDerivedA 和 BaseDeriveddB 的对象。这些对象需要在内存中对齐。我想提供一个迭代所有对象的迭代器。我想避免存储 Base 指针向量的内存开销。
为此,我构建了以下容器
struct Container {
std::vector<Base> bases;
std::vector<BaseDerivedA> derivedAs;
std::vector<BaseDerivedB> derivedBs;
// Iterator over the three vectors
all_iterator<Base> all_begin(){ return all_iterator(bases[0],this); }
all_iterator<Base> end_begin(){ return all_iterator(nullptr,this); }
// Where all_iterator is defined as
template < class T >
struct all_iterator
: public boost::iterator_facade< all_iterator<T>,
T, boost::forward_traversal_tag>
{
all_iterator() : it_(0) {}
explicit all_iterator(T* p, Container* c) // THIS JUST FEELS WRONG
: it_(p), c_(c) { }
private:
friend class boost::iterator_core_access;
T* it_;
Container* c_;
void increment() {
if (it_ == static_cast<T*>(&(c_->bases[c_->bases.size()-1]))) {
it_ = static_cast<T*>(&(c_->derivedAs[0]));
} else if (it_ == static_cast<T*>(&(c_->derivedAs[ds_->derivedAs.size()-1]))) {
it_ = static_cast<T*>(&(c_->derivedBs[0]));
} else if (it_ == static_cast<T*>(&(c_->derivedBs[ds_->derivedBs.size()-1]))) {
it_ = nullptr; // THIS DOES ALSO FEEL WRONG
} else {
++it_;
}
}
bool equal(all_iterator const& other) const {
return this->it_ == static_cast<T*>(other.it_);
}
T& dereference() const { return *it_; }
};
我使用 nullptr 作为过去的迭代器以及大量演员表。我还向我的迭代器传递了一个指向数据结构的指针。
有没有更好的方法来迭代三个包含 Base 类型或从 base 派生的类型的向量?
【问题讨论】:
-
您隐藏了大部分重要代码,例如
all_iterator是什么(它是如何定义的?)以及它如何使用它的参数。您的代码的当前实现(不管all_iterator)表现出未定义的行为:您无法访问derivedBs[derivedBs.size()],因为这是一个超出结尾的元素。 -
“我不能假设derivedBs 末尾的一个不是derivedAs 的第一个元素。” - 这是为什么?考虑到不同容器的迭代器是不可比较的,这是什么意思?
-
仍然,代码表现出未定义的行为,这意味着所有的赌注都被取消了。该方法不正确,您应该尝试找到解决方案,而不是尝试找到如何使未定义的行为起作用。
-
@DavidRodríguez-dribeas 我已经添加了迭代器的定义:)
-
我不明白用例。 BaseType 是 DerivedA 和 DerivedB 的基类吗?是否还有另一个类是 BaseType、DerivedA 和 DerivedB 的公共基础?