可变参数模板参数的函数链

时间:2014-12-08 03:03:02

标签: c++ templates opengl variadic-templates

我正在尝试设计一种通用的,类型安全的方法来将交错数据加载到OpenGL VBO中。我现在的问题是如何组织各种glVertexAttribPointer()调用。我已经定义了缓冲区数据描述符如下。

template <typename T>
struct Descriptor
{
    T vertex;
};

template <typename T, typename U>
struct Descriptor
{
    T vertex;
    U normal;
};
...

现在基本上都很简单。但是,我的问题是实际设置属性的模板函数如下所示。

template <template <class> class Desc, typename T>
void setAttributes(const Desc<T>& desc)
{
    // set attributes for vertices
    ...
    glVertexAttribPointer(0, sizeof(desc.vertex), ...);
}

template <template <class, class> class Desc, typename T, typename U>
void setAttributes(const Desc<T, U>& desc)
{
    // set attributes for vertices
    ...
    glVertexAttribPointer(0, sizeof(desc.vertex), ...);
    // set attributes for normals
    ...
    glVertexAttribPointer(1, sizeof(desc.normal), ...);
}
...

基本上问题是我仍然经历了很多重复。有没有办法将这些分解为两个模板函数,其中一个只设置顶点属性而另一个只设置法线?在伪代码中,如下所示。

template <class Desc, class T, Args...>
void setAttributes(Desc desc)
{
   setVertexAttributes(...);
   // somehow decide that if there are args left, call again...
}

template <class Desc, class U, Args...>
void setAttributes(Desc desc)
{
   // ...ending up here
   setNormalAttributes(...);
}

1 个答案:

答案 0 :(得分:0)

你说:

  

现在基本上都很简单。

在声明之前你所拥有的不好。

template <typename T>
struct Descriptor
{
    T vertex;
};

template <typename T, typename U>
struct Descriptor
{
    T vertex;
    U normal;
};

是无效的C ++。你不能像这样重载类模板。你可以这样做:

template <typename T>
struct Descriptor
{
    T vertex;
};

template <typename T, typename U>
struct Descriptor<std::pair<T, U>>
{
    T vertex;
    U normal;
};

template <typename T, typename U>
struct Descriptor
{
    T vertex;
    U normal;
};

template <typename T>
struct Descriptor<T, int>
{
    T vertex;
};

由于我不明白您打算如何使用它们,因此我无法确定哪一种更适合您的需求。