C++ class 成员模板函数,用于将 obj 插入成员 std::vector
C++ class member template function to insert an obj into a member std::vector
我如何创建一个模板函数,它可以将任何从游戏对象抽象 class 继承的 class 插入到已知类型的 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 switch case 并让编译器辨别哪个向量适合使用吗? (这可能是不可能的,但我听说编译时计算可以生成这样的代码)
提前致谢!
也许仍然使用函数调用重载,没有模板,主要是因为正如您正确推断的那样:它没有在此处添加任何内容:
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
我如何创建一个模板函数,它可以将任何从游戏对象抽象 class 继承的 class 插入到已知类型的 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 switch case 并让编译器辨别哪个向量适合使用吗? (这可能是不可能的,但我听说编译时计算可以生成这样的代码)
提前致谢!
也许仍然使用函数调用重载,没有模板,主要是因为正如您正确推断的那样:它没有在此处添加任何内容:
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