一次性定义结构并创建相关数据项列表?

Define a struct and create a list of related data items in one pass?

我想实现一个系统,通过该系统我可以使用一组宏(或模板)一次性创建一个结构和一些数据。它会像这样使用(语法不固定,任何有效的都可以):

def_vert(MyVertex)
{
    element(float, 3, Position,     POSITION, 0);
    element(float, 3, Normal,       NORMAL, 0);
    element(float, 2, UVa,          TEXCOORD, 0);
    element(float, 2, UVb           TEXCOORD, 1);
    element(float, 4, DiffuseColor, COLOR, 0);
}
end_def()

并且会输出:

struct MyVertex
{
    float3 Position;
    float3 Normal;
    float2 UVa;
    float2 UVb;
    float4 DiffuseColor;
};

还有:

field_definition MyVertex_field_defs[] =
{
    { "POSITION", 0, float_type, 3 },
    { "NORMAL", 0, float_type, 3 },
    { "TEXCOORD", 0, float_type, 2 },
    { "TEXCOORD", 1, float_type, 2 },
    { "COLOR", 0, float_type, 4 }
};

我看不到使用宏或 TMP 来执行此操作(创建 2 个单独的输出块)的方法 - 有人知道这是否可行吗?我无法直接使用 boost,但了解它是否能提供解决方案会很有用。

一个严峻的选择是使用像这样的包含文件:

MyVertex.h包含定义
def_makestruct.h 包含创建结构的宏
def_makefields.h 包含创建字段的宏

然后:

#include "def_makestruct.h"
#include "MyVertex.h"
#include "def_makefields.h"
#include "MyVertex.h"

所以我至少只需要在一个地方编辑定义,但它必须在它自己的文件中。有没有更好的方法?

我遇到了类似的问题,为了避免写两次相同的字符串,我使用了后续的技术。

定义将在文件上使用的宏:

在名为 data.cpp

的文件中只写入一次所需数据
mcr(NORMAL,3,Normal)
mcr(TEXCOORD,2,UVa)
mcr(TEXCOORD,2,UVb)
mcr(COLOR,4,DiffuseColor)

在另一个文件中写入

#define mcr(a,b,c,etc) define_as_needed
struct MyVertex
{
#include "data.cpp"
}
#undef mcr

#define mcr(a,b,c,etc) define_as_needed

而不是重新定义宏

#define mcr(a,b,c,etc) define_as_needed

field_definition MyVertex_field_defs[] =
{
#include "data.cpp"
};

#undef mcr

在我的例子中,根据每次需要更改宏定义的内容,我将上述重定义进行了 3 次,共 4 次。

根据您的需要调整代码。 特别是对于结构中常量和关联字符串和数据的定义,它非常方便。

您要实现的目标称为 X Macro

如果您不想在每个扩展站点包含任何文件或提供 element/def_vert/end_vert 定义,您可以将它们作为额外参数传递给 MyVertexDef 宏。

#define MyVertexDef(def_vert, element, end_def) \
def_vert(MyVertex) \
    element(float, 3, Position, POSITION, 0) \
    element(float, 3, Normal, NORMAL, 0) \
    element(float, 2, UVa, TEXCOORD, 0) \
    element(float, 2, UVb,           TEXCOORD, 1) \
    element(float, 4, DiffuseColor, COLOR, 0) \
end_def()

#define struct_def_vert(name) struct name {
#define struct_end_def() };
#define struct_element(type, size, name, meaning, index) type name; 

#define array_def_vert(name) field_definition name##_field_defs[] = {
#define array_end_def() };
#define array_element(type, size, name, meaning, index) {#name, index, type##_type, size},

#define GenerateStruct(T) T(struct_def_vert, struct_element, struct_end_def)
#define GenerateArray(T) T(array_def_vert, array_element, array_end_def)
...
//Where you want your struct MyVertex
GenerateStruct(MyVertexDef)
...
//Where you want MyVertex_field_defs
GenerateArray(MyVertexDef)