Я пытаюсь определить класс шаблона внутри нешаблонного класса, ниже вы можете увидеть код того, что я на самом деле пытаюсь сделать (он не компилируется по очевидной причине). Главный вопрос, как я могу понять, что с помощью C ++ 11 (предпочтительно) или C ++ 14?
На самом деле у меня есть решение с помощью станд :: вариант или та же функция из библиотеки BOOST, но мне нужно знать другой способ решить эту проблему.
Я нашел старый похожий вопрос, и ответ Энн Куинн звучит ценно (он предлагает объявлять подклассы для каждого типа, который мне нужен), но как применить это в коде, верно?
Код:
#include <vector>
#include <cstdint>
enum Type {
INT16,
UINT32
};
template<typename T>
class Buffer {
public:
Buffer(uint32_t paramSize) {
buffer.resize(paramSize);
}
private:
std::vector<T> buffer;
};
class Foo {
public:
Foo(Type paramType, uint32_t paramSize) {
switch(paramType) {
case UINT32:
buffer = Buffer<uint32_t>(paramSize);
break;
case INT16:
buffer = Buffer<int16_t>(paramSize);
break;
}
}
private:
Buffer buffer;
};
int main() {
Foo var(INT16, 30);
return 0;
}
UPD1: ответ @ user2308211, кажется, работает, но у меня есть две проблемы с этим. В случае, если я копирую объект Foo и оригинальный объект по какой-то причине разрушается (например, выходит из области видимости), копия останется с указателем в никуда. Второй — как получить мой буфер через класс Foo.
UPD2: shared_ptr решает проблему с копированием, но затем копия будет хранить тот же объект, в случае, если вы хотите изменить их независимо, используйте конструктор копирования, как показано в ответе. Что касается доступа к исходному буферу, указатель void позволяет вам получить указатель на вектор, тогда вы должны static_cast его для вашего типа.
Спасибо!
Иметь базовый класс со всеми необходимыми функциями для Buffer
как чисто виртуальный.
#include <vector>
#include <cstdint>
enum Type {
INT16,
UINT32
};
class BufferBase {
public:
virtual void someFn()=0;
virtual ~BufferBase() {}
};
template<typename T>
class Buffer:public BufferBase {
public:
Buffer(uint32_t paramSize) {
buffer.resize(paramSize);
}
void someFn() override {
//functionality.
}
~Buffer() {}
private:
std::vector<T> buffer;
};
class Foo {
public:
Foo(Type paramType, uint32_t paramSize) {
this->bufferType = paramType;
switch(paramType) {
case UINT32:
buffer = new Buffer<uint32_t>(paramSize);
break;
case INT16:
buffer = new Buffer<int16_t>(paramSize);
break;
}
}
~Foo() {
delete this->buffer;
}
Foo &operator=(const Foo &other) {
this->bufferType = other.bufferType;
switch(bufferType) {
case UINT32:
buffer = new Buffer<uint32_t>(*static_cast<Buffer<uint32_t>*>(other.buffer));
break;
case INT16:
buffer = new Buffer<int16_t>(*static_cast<Buffer<int16_t>*>(other.buffer));
break;
}
return *this;
}
Foo(const Foo &other) {
*this=other;
}
private:
BufferBase *buffer;
Type bufferType;
};
int main() {
Foo var1(INT16, 30), var2(UINT32, 25);
var1 = var2;
return 0;
}
РЕДАКТИРОВАТЬ: я обновил ответ с помощью конструктора копирования.
Других решений пока нет …