具有可选成员的 POD 模板类

POD Template class with optional members

本文关键字:POD 成员      更新时间:2023-10-16

我正在寻找一种方法来选择性地包含 c++ 类的成员以生成 POD 结构。我发现这工作得很好,但不是标准的:

#include <iostream>
template <int v, int n, int t>
struct Point
{
    int vertex[v];
    float normal[n];
    double texcoord[t];
};
int main()
{
    std::cout << (sizeof (Point<0,0,1>)) << std::endl;
    std::cout << (sizeof (Point<1,0,1>)) << std::endl;
    std::cout << (sizeof (Point<1,1,2>)) << std::endl;
    std::cout << (sizeof (Point<0,0,0>)) << std::endl;
    return 0;
}

所以 Point<1,0,0> 只包含一个顶点(int 类型在实践中实际上是 vector3 类型),依此类推。 这样做的主要原因是可以轻松支持 OpenGL 的交错阵列。

也许可以尝试这样的事情:

#include <type_traits>
template <unsigned int v, unsigned int n, unsigned int t>
struct Point
{
    int data[v + n + t];
    template <unsigned int i>
    typename std::enable_if<(i < v), int &>::type
    vertex() { return data[i]; }
    template <unsigned int i>
    typename std::enable_if<(i < v + n), int &>::type
    normal() { return data[v + i]; }
    template <unsigned int i>
    typename std::enable_if<(i < v + n + t), int &>::type
    texcoord() { return data[v + n + i]; }
};

用法:

Point<1,1,2> p;
p.vertex<0>() = 50;

>std::array<T, 0>是有效的,不像T[0],确实是一个更好的解决方案。不幸的是,由于这仅适用于 C++11,我无法弄清楚它的 Boost 同名boost::array是否也有这样的支持。

也可以自己编写类似array的助手。

你可以这样做,但你需要专业化。

编辑:与每个数组不同类型的新问题要求相匹配。虽然使模板参数未签名。

template <> struct Point<0, 0, 0> {};
template <unsigned v> struct Point<v, 0, 0> { int vertex[v]; };
template <unsigned n> struct Point<0, n, 0> { float normal[n]; };
template <unsigned t> struct Point<0, 0, t> { double texcoord[t]; };
template <unsigned v, unsigned n> struct Point<v, n, 0> {
    int vertex[v];
    float normal[n];
};
template <unsigned v, unsigned t> struct Point<v, 0, t> {
    int vertex[v];
    double texcoord[t];
};
template <unsigned n, unsigned t> struct Point<0, n, t> {
    float normal[n];
    double texcoord[t];
};

当每个专用化对应的模板参数具有值 0 时,都会省略关联的数组。对于所示的三个项目,专业化的枚举不是太大,并且提供了与原始帖子完全相同的语法来访问元素,但使用标准C++结构。

将此技术扩展到 3 个数组以上会很麻烦。但是,可以使用脚本对其进行管理,以为您生成专业化。