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