我基本上试图将模板类存储在单个std :: vector中。我使用的是目前的解决方案是包含类型的匿名联合的结构:将模板类存储到矢量中
struct SurfaceUnion
{
enum { INT, FLOAT }Tag;
union
{
GLSurface<int>* iGLSurface;
GLSurface<float>* fGLSurface;
};
};
std::vector<SurfaceUnion*> vglSurfaces;
的问题,这是事实,为了解析我需要哪个GLSurface,我必须做这样的事情:
for (unsigned int i = 0; i < vglSurfaces.size(); ++i)
{
switch (vglSurfaces[i]->Tag)
{
case SurfaceUnion::INT:
{
if (vglSurfaces[i]->iGLSurface->bIsActive && a_Camera.GetWorldSpace() == vglSurfaces[i]->iGLSurface->uiWorldSpace)
{
DrawSurface(*vglSurfaces[i]->iGLSurface, a_Camera);
}
break;
}
case SurfaceUnion::FLOAT:
{
if (vglSurfaces[i]->fGLSurface->bIsActive && a_Camera.GetWorldSpace() == vglSurfaces[i]->fGLSurface->uiWorldSpace)
{
DrawSurface(*vglSurfaces[i]->fGLSurface, a_Camera);
}
break;
}
}
}
然后我终于可以与GLSurface直接交互,并在不使用复制粘贴代码
template <typename T, typename U>
void DrawSurface(const GLSurface<T>& ac_glSurface, const Camera<U>& a_Camera)
{
glPushMatrix(); // Save the current matrix.
glTranslatef( // Move the image back to its original position
ac_glSurface.Pos.X + (ac_glSurface.Center.X - ac_glSurface.OffsetD.W/2),
ac_glSurface.Pos.Y + (ac_glSurface.Center.Y - ac_glSurface.OffsetD.H/2),
0.0f);
glScalef(ac_glSurface.Scale.W, ac_glSurface.Scale.H, 0.0f); // Scale the image
glRotatef(ac_glSurface.Rotation, 0.0f, 0.0f, 1.0f); // Rotate the image
glTranslatef( // Move the image to (0,0) on the screen
-ac_glSurface.Pos.X - (ac_glSurface.Center.X - ac_glSurface.OffsetD.W/2),
-ac_glSurface.Pos.Y - (ac_glSurface.Center.Y - ac_glSurface.OffsetD.H/2), 0.0f);
DrawSurface(ac_glSurface);
glPopMatrix(); // Reset the current matrix to the one that was saved.
}
template <typename T>
void DrawSurface(const GLSurface<T>& ac_glSurface)
{
// Drawing the surface using glDrawArrays is here
}
办法,我也有一个摄像头,以及!每次我需要对Camera或GLSurface做某些事情时,这是太多的解析。这两个实现结合在一起完全从我试图创建的代码中移除了真正的通用性。现在你只能有一个int和一个float类型。要添加任何其他内容,我必须重写大部分代码才能解析额外的类型。更不用说这是为了成为.lib的一部分,所以如果将来需要考虑的话,它不能在没有重新编译.lib的情况下添加。此外,诸如以下呼叫:
template <typename T>
void DeleteSurface(GLSurface<T>* a_pglSurface)
{
for (int i = 0; i < vglSurfaces.size(); ++i)
{
switch (vglSurfaces[i]->Tag)
{
case SurfaceUnion::INT:
{
if (vglSurfaces[i]->iGLSurface == a_pglSurface)
{
auto DeleteSurface = vglSurfaces[i]->iGLSurface;
vglSurfaces.erase(vglSurfaces.begin() + i);
glDeleteTextures(1, &DeleteSurface->Surface);
delete DeleteSurface;
}
break;
}
case SurfaceUnion::FLOAT:
{
// Will throw an error if uncommented
/*if (vglSurfaces[i]->fGLSurface == a_pglSurface)
{
auto DeleteSurface = vglSurfaces[i]->fGLSurface;
vglSurfaces.erase(vglSurfaces.begin() + i);
glDeleteTextures(1, &DeleteSurface->Surface);
}
break;*/
}
}
}
}
由于模板化函数的工作方式,所以不可行。我需要像过去那样完成这2个函数,并且在解析正确的类型之后再调用另一个函数。
那么,有没有更好的方式来使用当前的实现?正如在我可以解析通过连接到'标记'枚举的未知数量的类型?还是完全有另一种实现?
我知道'增强'库,但是这远不是轻量级的增加,它似乎并不是我一直在寻找的东西。我需要直接修改GLSurface的值,并且在访问者函数之后不能真正调用访问者函数。我有20个访问者函数,并且我对目前的实现不满意的原因是它在解析后失去了通用性和多余的函数调用。我基本上有同样的事情,我现在有,但有一个巨大的依赖性包括文件夹
我也知道多态的,但我不认为有一个基类,将帮助,因为我需要看不同类型的成员变量,基类不允许我这样做。
任何帮助是非常赞赏,因为我一直坚持这个可怕的代码,我已经很长一段时间写的。
我没有阅读所有文章,但是'std :: vector>'有什么问题? –
Jepessen
同样在这里。通读并无法弄清楚有两个不同的实例是什么点。 – SergeyA
这是所有名字空间的内部。即使不是这样,关键是将GLSurface和GLSurface 放在同一个向量中......除非T被定义为类型,否则不能只说std :: vector <'MyClass'>我知道,这种类型是绝对的,这意味着它不能从int变为float。这是除非我根本不了解模板。 –
bennybroseph