내가 가진 가정 할 vector
(또는 list
또는 무엇이든 용기 여기에 더 적합 할 수 있음) 나는 템플릿 유형의 여러 객체 (또는 포인터)를 저장하고 싶다고 :
std::vector<MyClass<double>> v;
// std::vector<MyClass<double> *> v;
안타깝게도이 컨테이너에 다른 템플릿 객체를 저장하고 싶습니다 (이상적으로 일정한 시간에 액세스해야합니다).
내 첫 번째 직관은 내부적 으로 멤버 변수로 모든 것을 관리하는 일종의 WrapperClass
주위 를 만드는 MyClass
것이 MyClass
었지만 적절한 유형을 MyClass
다음 과 같이 전달할 수있는 방법이 명확하지 않습니다 .
#include <iostream>
#include <string>
#include <stdlib.h>
#include <vector>
using namespace std;
template<typename T>
class MyClass
{
public:
MyClass() {}
~MyClass() {}
};
// templating this of course works, but it doesn't solve my problem
template<typename T>
class WrapperClass
{
public:
WrapperClass()
{
m_object = MyClass<T>();
}
~WrapperClass() { }
private:
MyClass<T> m_object;
};
int main()
{
WrapperClass<bool> tmp = WrapperClass<bool>();
std::vector<WrapperClass<bool> *> v;
return 0;
}
그래서이 (A) 과는 다른 컨테이너가 vector
나는이 문제 나에 사용 될 수 있음 (B) 의 종류를 선택하는 방법 MyClass
에 WrapperClass
생성자 내부를? 나는 다음과 같은 라인을 따라 무언가를 생각하고 있었다.
class WrapperClass2
{
public:
WrapperClass2(unsigned int typeId)
{
switch (typeId)
{
case 0: m_object = new MyClass<bool>();
case 1: m_object = new MyClass<int>();
case 2: m_object = new MyClass<float>();
default: m_object = new MyClass<double>();
}
}
~WrapperClass2()
{
delete m_object;
}
private:
MyClass * m_object;
};
또 다른 아이디어는 AbstractType
벡터에서 사용할 부모를 갖는 것이지만 템플릿 형식 문제에 어떻게 도움이 될지 모르겠습니다.
클래스 템플릿의 다른 인스턴스화는 완전히 관련되지 않은 유형이므로 직접 저장하는 컨테이너를 가질 수 없습니다.
몇 가지 옵션이 있습니다.
class Base
{
virtual ~Base {}
virtual void someMethod() const = 0;
};
template <typename T>
class MyClass : public Base
{
void someMethod() const
{
// stuff
}
};
int main()
{
std::vector<std::unique_ptr<Base>> objs;
objs.push_back(std::make_unique<MyClass<int>>());
objs.push_back(std::make_unique<MyClass<std::string>>());
for (auto i : objs) {
i->someMethod();
}
}
이것은 매우 간단한 접근 방식이지만 동적 할당 및 RTTI로 인해 약간의 런타임 오버 헤드가 발생합니다. 또한 무엇인지 모르는 부모 클래스의 메서드이기 때문에 someMethod
반환 할 수 없습니다 .T
T
boost::any
(또는 std::any
C ++ 17에서 제공 될 것 )를 사용합니다.#include <any>
#include <string>
#include <vector>
template <typename T>
class MyClass {
public:
T someMethod() const {
// stuff
return {};
}
};
void someFunctionThatTakesInt(int i) {}
void someFunctionThatTakesString(std::string s) {}
int main() {
std::vector<std::any> objs;
objs.push_back(MyClass<int>());
objs.push_back(MyClass<std::string>());
for (const auto& i : objs) {
if (i.type() == typeid(MyClass<int>)) {
auto& mc = std::any_cast<const MyClass<int>&>(i);
someFunctionThatTakesInt(mc.someMethod());
} else if (i.type() == typeid(MyClass<std::string>)) {
auto& mc = std::any_cast<const MyClass<std::string>&>(i);
someFunctionThatTakesString(mc.someMethod());
}
}
}
이 접근 방식은 someMethod
return 을 가질 수 있음을 의미 T
하지만 객체를 사용 vector
하기 전에 어떤 유형인지 파악해야하기 때문에 객체 검색을 처리하기가 훨씬 더 어려워집니다 (기본적으로 자체 RTTI를 롤링합니다).
처음에 이것이 필요한 이유를 다시 생각하십시오. 다른 방법이 더 잘 작동 할 수 있습니다. 콜백이나 방문자가있는 것일 수도 있습니다. 나는 여기서 당신의 목표를 모르기 때문에 무엇이 적절한 지 정말로 말할 수 없습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다