假设我有一个vector
(or list
或任何可能更适合这里的容器),我想将模板化类型的多个对象(或指针)存储在:
std::vector<MyClass<double>> v;
// std::vector<MyClass<double> *> v;
不幸的是,我想在这个容器中存储不同的模板化对象(并且理想情况下我需要在恒定的时间访问它们)。
我的第一直觉是创造某种WrapperClass
around 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
in 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
is.
- 使用某种类型擦除的包装器,例如
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)。
- Don't.
首先重新思考一下为什么你需要这个。也许另一种方法可能效果更好。也许有回调或访客的东西。我不知道你的目的,所以我不能说什么是合适的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)