我试图实现以下目标:给定一个抽象类MemoryObject,每个类都可以继承它,我有两个子类:Buffer和Buffer>大缓冲区:
template <typename T>
class MemoryObject
{
public:
typedef typename std::vector<T>::iterator iterator;
typedef typename std::vector<T>::const_iterator const_iterator;
[...] //Lot of stuff
virtual iterator begin() = 0;
virtual iterator end() = 0;
};
缓冲区:
template <typename T>
class Buffer: public MemoryObject<T>
{
public:
typedef typename std::vector<T>::iterator iterator;
iterator begin() { return buffer_.begin(); }
iterator end() { return buffer_.end(); };
[...] //Lot of stuff
private:
std::vector<T> buffer_;
};
最后:
template <typename T>
class BigBuffer: public MemoryObject<T>
{
public:
[...] //Omitted, for now
private:
std::vector<Buffer<T>*> chunks_;
};
正如你所看到的,一个BigBuffer保存了一个Buffer
template <class KernelType, typename T>
void fill(CommandQueue<KernelType>& queue, MemoryObject<T>& obj, const T& value)
{
//Do something with obj
}
有什么意义? - 你可能会问。关键是我必须在这些类上实现迭代器。我已经为 Buffer 实现了它们,这正是我所需要的:能够迭代 Buffer 并访问范围(例如 b.begin() ,b.begin() + 50)。 显然我不能对 BigBuffer 做同样的事情,因为真实数据(位于每个 Buffer 的私有(private)变量 buffer_ 内)分散在各个地方内存。所以我需要一个新类,我们称之为 BigBufferIterator,它可以重载 * 或 + 等运算符,允许我从一个内存块“跳转”到另一个内存块,而不会引发段错误。
问题有两个:
- MemoryObject的迭代器类型与迭代器不同
BigBuffer 的类型:前者是 std::vector
::iterator,后者是 后者是一个 BigBufferIterator。我的编译器明显提示 - 我希望能够保留函数签名的通用性
仅向它们传递 MemoryObject
&,而不是专门用于 每个类类型。
我试图解决第一个问题,添加一个名为 Iterator 的模板参数,并为每个类提供一个默认参数,模型松散地基于 Alexandrescu 的基于策略的模型。这个解决方案解决了第一个问题,但没有解决第二个问题:当我尝试将 BigBuffer 传递给函数(例如, fill() )时,我的编译仍然提示,告诉我:“未知从 BigBuffer 到 MemoryObject 的转换”。这是因为迭代器类型不同..
我对这首诗感到非常抱歉,但这是向你正确表达我的问题的唯一方法。我不知道为什么有人会费心去阅读这些东西,但我会碰碰运气。
预先感谢您阅读到这里。
谦虚地说, 阿尔弗雷多
最佳答案
他们的方法是使用最通用的定义作为基的迭代器类型。也就是说,您希望将 Buffer
中的数据视为一个段,而 BigBuffer
则是一系列相应段。这有点不幸,因为这意味着您将 Buffer 中单个缓冲区的迭代器视为多个缓冲区,即您有一个只有一个段的分段结构。然而,与替代方案(即具有由句柄包装的虚拟函数的迭代器层次结构,为这种困惑提供值语义)相比,您实际上并没有付出太大的成本。
关于C++ : Using different iterator types in subclasses without breaking the inheritance mechanism,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9239489/