将模板化的类存储到向量中
Storing templated class into vector
我基本上是想把模板化的类存储在一个std::向量中。我目前使用的解决方案是一个包含以下类型的匿名联合的结构:
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
}
我也有一个相机!每次我需要对相机或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;*/
}
}
}
}
由于模板化函数的工作方式,这是不可能的。我需要像过去一样制作这两个函数,并在解析正确的类型后调用其中一个。
那么,有没有更好的方法来使用当前的实现呢?在中,我可以解析连接到"标记"枚举的未知数量的类型吗?还是完全有另一种实现?
我知道"boost"库,但这远不是一个轻量级的添加,而且它似乎不是我最初想要的。我需要直接修改GLSurface的值,不能只为它调用一个又一个访问者函数。我有20个访问者函数,我对当前实现不满意的原因是它在解析后失去了泛型和多余的函数调用。我基本上会有和现在一样的东西,但有一个巨大的依赖,包括文件夹
我也知道多态性,但我不认为有基类会有帮助,因为我需要查看不同类型的成员变量,而基类不允许我这样做
任何帮助都是非常感谢的,因为我已经被这个糟糕的代码卡住了很长一段时间。
您不能存储不同的类型。
可以通过多态引用(std::reference_wrapper)或(智能)指针存储动态实例,前提是类共享一个公共基。
否则,您应该使用静态多态性。例如,您可以查看boost::variant<GLSurface<float>, GLSurface<int>>
。
为了统一地操作这些,您最终会做一些静态和运行时多态性的混合:类型擦除。
使用类型擦除技术,您基本上将(不相关的)类型置于共享的特别接口下。
- 访问存储在向量C++中的结构的多态成员
- 添加存储在向量中的大整数的函数出现问题
- 在 std::无符号字符的向量处存储 int 的十六进制表示形式
- 如何从用户那里获取输入并将其存储在向量中?
- 如何从文件中读取两个字符串和数字数组,并将它们存储在对象向量中
- 将无符号字符的向量存储在数组中会给我 std::bad_alloc
- 在二维向量或数组中可以存储的最大元素数是多少?
- 存储在堆分配向量中的指针的免费存储
- 将相同共享指针的副本存储在不同的向量中是否是一种好的做法?
- 将数组信息存储到 c++ 向量中有一个"Access violation reading location"
- Sqlite3:将数据库表名存储在向量中
- 如何在数组和向量 c++ 中存储和保存输入
- C++ 将抽象类型的动态分配对象传递给函数并存储在向量中
- 是否可以在类中存储unique_ptr,并在C++中存储向量?
- 在向量 C++14(无限制联合)的结构内的联合中创建和存储字符串
- 在固定大小的向量中存储指向元素的指针
- 无法将派生类存储在基类指针的向量中
- 如何访问和存储向量类型的结构成员
- 如何按索引存储向量的向量
- findnonzero() 中存储向量<Point>中非零元素的坐标时出错