C ++ выбирает тип шаблона члена класса в конструкторе

Я пытаюсь определить класс шаблона внутри нешаблонного класса, ниже вы можете увидеть код того, что я на самом деле пытаюсь сделать (он не компилируется по очевидной причине). Главный вопрос, как я могу понять, что с помощью C ++ 11 (предпочтительно) или C ++ 14?

  1. На самом деле у меня есть решение с помощью станд :: вариант или та же функция из библиотеки BOOST, но мне нужно знать другой способ решить эту проблему.

  2. Я нашел старый похожий вопрос, и ответ Энн Куинн звучит ценно (он предлагает объявлять подклассы для каждого типа, который мне нужен), но как применить это в коде, верно?

Код:

#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 его для вашего типа.

Спасибо!

0

Решение

Иметь базовый класс со всеми необходимыми функциями для 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;
}

РЕДАКТИРОВАТЬ: я обновил ответ с помощью конструктора копирования.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]