Я пытаюсь добиться следующего: учитывая абстрактный класс MemoryObject , который может наследовать каждый класс, у меня есть два подкласса: A Buffer и BigBuffer
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 содержит std :: vector из Буфер *, поэтому вы можете просматривать BigBuffer в виде агрегации буфера (ов). Кроме того, у меня есть несколько функций, которые должны работать с каждым объектом MemoryObject, так что это настоящая подпись:
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 'закрытой переменной buffer_ ) разбросаны по всей памяти. Поэтому мне нужен новый класс, давайте назовем его BigBufferIterator , который может перегрузить оператор, такой как * или +, что позволяет мне «перепрыгивать» из куска памяти в другой, не вызывая ошибки сегментации.
Проблемы две:
- Тип итератора MemoryObject отличается от итератора.
тип BigBuffer : первым является std :: vector :: iterator,
последний BigBufferIterator . Мой компилятор явно жалуется
- Я хочу быть в состоянии сохранить универсальность сигнатур моих функций
передавая им только MemoryObject &, не специализируя их на
каждый тип класса.
Я попытался решить первую проблему, добавив классный параметр класса Iterator и присвоив ему аргумент по умолчанию для каждого класса, с моделью, слабо основанной на модели Александреску, основанной на политике. Это решение решило первую проблему, но не вторую: мой скомпилированный все еще жалуется, говоря мне: «Неизвестное преобразование из BigBuffer в MemoryObject», когда я пытаюсь передать BigBuffer в функцию (например, fill ()). Это потому, что типы итераторов различны ..
Мне очень жаль это стихотворение, но это был единственный способ правильно представить вам мою проблему. Я не знаю, почему кто-то вообще потрудился бы прочитать все эти вещи, но мне повезет.
Заранее спасибо, только что прочитали до этого момента.
Смиренно,
Alfredo