简体   繁体   English

具有可选成员的 POD 模板类

[英]POD Template class with optional members

I am looking for a way to optionally include members of a c++ class to generate POD structs.我正在寻找一种方法来选择性地包含 c++ 类的成员以生成 POD 结构。 I found that this works fairly well, but is nonstandard:我发现这工作得很好,但不是标准的:

#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;
}

So Point<1,0,0> would only contain a vertex (the int type will actually be a vector3 type in practice), and so on.所以 Point<1,0,0> 只会包含一个顶点(实际上 int 类型实际上是 vector3 类型),依此类推。 The main reason for this is to easily support interleaved arrays for OpenGL.这样做的主要原因是为了轻松支持 OpenGL 的交错数组。

Maybe try something like this:也许尝试这样的事情:

#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]; }
};

Usage:用法:

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

std::array<T, 0> is valid, unlike T[0] and really is a better solution all around. std::array<T, 0>是有效的,不像T[0]并且确实是一个更好的解决方案。 Unfortunately, and since this is only available for C++11, I can't figure out if its Boost namesake boost::array also has such support.不幸的是,由于这仅适用于 C++11,我不知道它的 Boost 同名boost::array是否也有这样的支持。

It is also possible to write an array -like helper yourself.也可以自己编写一个类似array的助手。

You can do this, but you would need specializations.你可以做到这一点,但你需要专业化。

Edit: Matched with new question requirement of different type per array.编辑:匹配每个数组不同类型的新问题要求。 Made template arguments unsigned though.虽然使模板参数无符号。

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];
};

Each specialization leaves out the associated array when its corresponding template parameter has value 0 .当对应的模板参数的值为0时,每个特化都会省略关联的数组。 For three items as shown, the enumeration of specializations is not overly large, and provides exactly the same syntax for accessing the elements as your original post but using standard C++ constructs.对于所示的三个项目,专门化的枚举并不过分大,并且提供与原始帖子完全相同的访问元素的语法,但使用标准 C++ 构造。

Extending this technique beyond 3 arrays would be cumbersome.将此技术扩展到 3 个阵列之外会很麻烦。 However, it could be managed with a script to generate the specializations for you.但是,可以使用脚本对其进行管理,为您生成专业化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM