如何创建一个模板函数,可以将任何继承的类从游戏obj抽象类插入到已知类型的std向量中?
这是一些有意义的代码,请注意它不应该能够编译:
enum GAMEOBJ_TYPE {
WIRE = 'w',
GATE = 'g',
};
std::vector<Wire*> wires;
std::vector<Gate*> gates;
template <typename T>
void SortAndInsertIntoVector (T *obj, GAMEOBJ_TYPE type ) {
switch (type) {
case WIRE:
wires.push_back(obj);
break;
case GATE:
gates.push_back(obj);
break;
}
}
据我所知,编译器生成代码并将T替换为编译器在每次调用此模板函数时找到的类型,以生成每种类型的函数模板。 因此,我们将获得2个新功能:
void SortAndInsertIntoVector_CompilerMangled_Wire (Wire *obj, GAMEOBJ_TYPE type ) {
switch (type) {
case WIRE:
wires.push_back(obj);
break;
case GATE:
gates.push_back(obj);
break;
}
}
void SortAndInsertIntoVector_CompilerMangled_Gate (Gate *obj, GAMEOBJ_TYPE type ) {
switch (type) {
case WIRE:
wires.push_back(obj);
break;
case GATE:
gates.push_back(obj);
break;
}
}
因此,我们会在这一代中得到编译器错误,因为Wire类型无法插入到门矢量中,反之亦然。
是否有更好的方法对此进行编码,以便除了手动重载函数之外,我可以将obj插入到右侧向量中。 (想象一下,如果我有20种类型的游戏对象)
还有一个更好的优化,我可以做的是在函数中没有ENUM开关盒,让编译器辨别哪个向量适合使用? (这可能是不可能的,但我听说编译时计算可以生成这样的代码)
提前致谢!
答案 0 :(得分:2)
也许仍然使用函数调用重载,没有模板,主要是因为正确推断:它不会在这里添加任何内容:
void SortAndInsertIntoVector (Wire* obj) {
wires.push_back(obj);
}
void SortAndInsertIntoVector (Gates* obj) {
gates.push_back(obj);
}
这消除了对ENUM的需要并且将提供类型安全性,并且您可以为您(有限的,我希望的)数量类型使用相同的函数调用。
编辑:如果您辞职时没有通过名称明确命名目标向量,这是使用模板进行操作的一种方法。在下面的建议中,您始终可以通过以下方式访问存储的对象: gameobs<Wire*>::theObjects
:
#include <vector>
#include <iostream>
using namespace std;
template <typename T>
struct gameobjs {
static vector<T> theObjects;
};
template <typename T>
vector<T> gameobjs<T>::theObjects;
template <typename T>
void SortAndInsertIntoVector(T* obj) {
gameobjs<T*>::theObjects.push_back( obj );
}
int main( void ) {
SortAndInsertIntoVector((int*)0);
SortAndInsertIntoVector((float*)0);
cout << "Number of ints: " << gameobjs<int*>::theObjects.size() << endl;
cout << "Number of floats: " << gameobjs<float*>::theObjects.size() << endl;
cout << "Number of chars: " << gameobjs<char*>::theObjects.size() << endl;
}
哪个输出:
Number of ints: 1
Number of floats: 1
Number of chars: 0