.net Boost预处理器库,用于根据基本类型列表生成一组类型,例如C+中的PointI32、PointF32等+/CLI

.net Boost预处理器库,用于根据基本类型列表生成一组类型,例如C+中的PointI32、PointF32等+/CLI,.net,boost,c++-cli,boost-preprocessor,.net,Boost,C++ Cli,Boost Preprocessor,我试图弄清楚如何使用Boost.Preprocessor库为不同的特定类型展开“泛型”类型。下面我将问一个简单的point类示例。鉴于: struct Point##TYPE_SUFFIX_NAME { TYPE X; TYPE Y; // Other code }; 我想为不同的基本(POD)数据类型生成此类型,例如: PointF32, PointF64, PointI32 etc. 其中,点F32将是: struct PointF32 { float

我试图弄清楚如何使用Boost.Preprocessor库为不同的特定类型展开“泛型”类型。下面我将问一个简单的point类示例。鉴于:

struct Point##TYPE_SUFFIX_NAME
{
    TYPE X;
    TYPE Y;

    // Other code
};
我想为不同的基本(POD)数据类型生成此类型,例如:

PointF32, PointF64, PointI32 etc.
其中,点F32将是:

struct PointF32
{
     float X;
     float Y;
};
也就是说,根据类型列表:

short, int, long, float, double etc. 
我想“展开”这些上面的类型。最好将“模板”定义放在单独的include文件中,而不是作为宏,以便于调试

注:我对C++模板的听力不感兴趣。我知道如何使用模板。但这些在我的情况下是没有用的。例如,假设这些类型将在C#中从.NET使用,但在C++/CLI中生成。所以请坚持这个问题

当然,问题是由于.NET中缺少模板支持,而泛型不适合解决我的问题。

< P>旧的(预模板)版本的C++编译器经常会出现这样的事情:<代码> <代码>标题。我会在g++的旧版本中搜索它。那是在我出生之前,所以我不知道它是否适合你

或者,类似于

#define TYPE short
#define TYPES I16
#include "Point.def"
#undef TYPE
#undef TYPES
#define TYPE int
#define TYPES I32
#include "Point.def"
我也可以帮你


或明显是外部代码生成器(在AWK、Perl、C++中,无论什么)。这可能是最好的解决方案。

以下代码未经测试,但应该是实现所需的一个良好开端

在my_structures.h中:

#ifndef __MYSTRUCTURES_H__
#define __MYSTRUCTURES_H__

#define MY_LIST_OF_TYPES (F32, (I32, (BOOST_PP_NIL)))
#define MY_LIST_OF_SUFFICES (float, (int, (BOOST_PP_NIL)))

#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/list/size.hpp>

#define BOOST_PP_ITERATION_LIMITS (0, BOOST_PP_LIST_SIZE(MY_LIST_OF_TYPES))
#define BOOST_PP_FILENAME_1       "create_my_structures.h"
#include BOOST_PP_ITERATE()

#undef MY_LIST_OF_TYPES
#undef MY_LIST_OF_SUFFICES
#endif
\ifndef\uuu MYSTRUCTURES\uh__
#定义我的结构__
#定义类型(F32,(I32,(BOOST\u PP\u NIL))的我的\u列表
#定义我的清单(float,(int,(BOOST_PP_NIL)))
#包括
#包括
#定义BOOST\u PP\u迭代限制(0,BOOST\u PP\u列表大小(我的列表类型))
#定义BOOST_PP_FILENAME_1“create_my_structures.h”
#包括BOOST_PP_ITERATE()
#取消定义\u类型的我的\u列表\u
#取消定义我的\u列表\u
#恩迪夫
在“创建我的结构”中

#include <boost/preprocessor/list/at.hpp>

#define n BOOST_PP_ITERATION()

struct Point ## BOOST_PP_LIST_AT(MY_LIST_OF_SUFFICES, n)
{
  BOOST_PP_LIST_AT(MY_LIST_OF_TYPES, n) X;
  BOOST_PP_LIST_AT(MY_LIST_OF_TYPES, n) Y;
};

#undef n
#包括
#定义n个BOOST_PP_迭代()
结构点###BOOST#PP(u列表)AT(我的列表)OF(u足够了,n)
{
(类型的我的列表,n)X处的BOOST_PP_LIST_;
在(类型的我的列表,n)Y处增加列表;
};
#未定义的

根据贝诺特的回答,我得出了以下答案。答案由三个文件组成:

  • MyPointTypes.h
  • MyPointTypeImpl.h
  • MyPointTypes.cpp
MyPointTypes.h:

#ifndef __MYSTRUCTURES_H__
#define __MYSTRUCTURES_H__

#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/seq/size.hpp>

typedef signed char int8;
typedef unsigned char uint8;
typedef signed short int16;
typedef unsigned short uint16;
typedef signed int int32;
typedef unsigned int uint32;
typedef signed int int64;
typedef unsigned int uint64;

typedef float float32;
typedef double float64;

#define MY_SIGNED_INTEGER_SEQ    (int8)(int16)(int32)(int64)
#define MY_SIGNED_INTEGER_SUFFIX_SEQ    (I8)(I16)(I32)(I64)

#define MY_UNSIGNED_INTEGER_SEQ    (uint8)(uint16)(uint32)(uint64)
#define MY_UNSIGNED_INTEGER_SUFFIX_SEQ    (UI8)(UI16)(UI32)(UI64)

#define MY_SIGNED_UNSIGNED_INTEGER_SEQ    MY_SIGNED_INTEGER_SEQ MY_UNSIGNED_INTEGER_SEQ
#define MY_SIGNED_UNSIGNED_INTEGER_SUFFIX_SEQ    MY_SIGNED_INTEGER_SUFFIX_SEQ MY_UNSIGNED_INTEGER_SUFFIX_SEQ

#define MY_FLOAT_SEQ    (float32)(float64)
#define MY_FLOAT_SUFFIX_SEQ    (F32)(F64)

#define MY_BASIC_NUMERIC_TYPES_SEQ    MY_SIGNED_UNSIGNED_INTEGER_SEQ MY_FLOAT_SEQ
#define MY_BASIC_NUMERIC_TYPES_SUFFIX_SEQ    MY_SIGNED_UNSIGNED_INTEGER_SUFFIX_SEQ MY_FLOAT_SUFFIX_SEQ


#define MY_SEQ_OF_TYPES    MY_BASIC_NUMERIC_TYPES_SEQ
#define MY_SEQ_OF_SUFFICES    MY_BASIC_NUMERIC_TYPES_SUFFIX_SEQ

#define BOOST_PP_ITERATION_LIMITS (0, BOOST_PP_SEQ_SIZE(MY_SEQ_OF_TYPES) - 1)
#include BOOST_PP_ITERATE()

#undef MY_SEQ_OF_TYPES
#undef MY_SEQ_OF_SUFFICES

#endif
这将定义以下类型:

PointI8, PointI16, PointI32, PointI64, 
PointUI8, PointUI16, PointUI32, PointUI64, 
PointF32, PointF64

想象一下,而不是C++结构体,即C++ +CLI值类型,即:

public value class Point 

然后我们有效地创建了所有基本数字类型的点类型,用于.NET中,例如C#。

这似乎是一个老问题,但。。。。 我认为仅使用标准宏处理器(CPP)更容易做到这一点

或者这种变化(遵循“规范”)


只是为了确保我理解这个问题。您要做的是定义类型后缀列表和类型列表之间的对应关系,并让一些boost预处理器魔法接管并生成所有对应的类型。是吗?没错。我可能会添加我使用VisualC++ 2008的特性包。我会得到以下错误:警告C400:宏的“BooStPypppListFixTysI”警告C400没有足够的实际参数:宏的“BooStPypp.ListHisturi”没有足够的实际参数,并且看起来预处理器的输出类似于:公共值类的点{int X;int Y;};因此后缀和类名没有连接。好的,我已经解决了concat问题。新的create_my_结构。h现在是:#include#define n BOOST_PP_ITERATION()#define PASTER(X,Y)X#Y#define EVALUATOR(X,Y)PASTER(X,Y)#define CONCATEVALUATED(X,Y)define CONCATEVALUATED(X,Y)define后缀BOOST#PP#LIST(MY_LIST_OF_sufficies,n)#define TYPE BOOST_PP_LIST_AT(MY_LIST_OF_TYPES,n)#define ADDSUFFIX(cls)CONCATEVALUATED(cls,SUFFIX)struct ADDSUFFIX(Point){TYPE X;TYPE Y;};#undef n(遗憾的是,注释不能有正确的代码粘贴)。也许,您可以编辑您的答案以反映这一点。但是,由于上述警告,它仍然不起作用。它似乎还显示了终止和类似情况:struct PointBOOST_PP_NIL{BOOST_PP_NIL X;BOOST_PP_NIL;};struct PointBOOST_PP_LIST_FIRST{BOOST_PP_LIST_FIRST_I X;BOOST_PP_LIST_FIRST_I;};嗨,我终于想出了如何使用序列而不是列表来完成这项工作。我想将此作为一个答案发布,但这意味着你(Benoît)将无法获得回答的荣誉,尽管你基本上已经回答了。你觉得这样可以吗?(抱歉,所有评论)这个解决方案我知道,但并不完全是我想要的。虽然它很有效:)看看我自己基于Benoîts答案的答案。A+1会很好。好吧,这确实解决了问题(这是我一直在使用的解决方案)但它也有一些缺点。主要的缺点是,由于只有一行代码,因此“全是宏”调试变得困难。此外,与“包含”方法相比,代码必须声明为宏,这使得编辑更加困难。
PointI8, PointI16, PointI32, PointI64, 
PointUI8, PointUI16, PointUI32, PointUI64, 
PointF32, PointF64
public value class Point 
#define STRUCT_POINT( P_TYPE ) \
struct Point##_##P_TYPE        \
{                              \
   P_TYPE X;                   \
   P_TYPE Y;                   \
                               \
};

#define CREATE_STRUCT_POINTS \
  STRUCT_POINT( short    )     \
  STRUCT_POINT( int      )     \
  STRUCT_POINT( unsigned )     \
  STRUCT_POINT( float    )     \
  STRUCT_POINT( double   )

CREATE_STRUCT_POINTS

#undef CREATE_STRUCT_POINTS
#undef STRUCT_POINT
#define STRUCT_POINT( P_TYPE, P_TYPE_ALIAS ) \
struct Point##P_TYPE_ALIAS     \
{                              \
   P_TYPE X;                   \
   P_TYPE Y;                   \
                               \
};

#define CREATE_STRUCT_POINTS \
  STRUCT_POINT( short    ,  I16  )     \
  STRUCT_POINT( int      ,  I32  )     \
  STRUCT_POINT( unsigned ,  U32  )     \
  STRUCT_POINT( float    ,  F32  )     \
  STRUCT_POINT( double   ,  F64  )

CREATE_STRUCT_POINTS

#undef CREATE_STRUCT_POINTS
#undef STRUCT_POINT