C ++类成员模板函数将obj插入到成员std :: vector中

时间:2015-03-02 15:12:34

标签: class templates c++11 vector

如何创建一个模板函数,可以将任何继承的类从游戏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开关盒,让编译器辨别哪个向量适合使用? (这可能是不可能的,但我听说编译时计算可以生成这样的代码)

提前致谢!

1 个答案:

答案 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