And*_*s T 2 c c++ macros templates multiple-definition-error
我试图从C中的C++标准库重新创建一些类.例如,std :: pair类.
为了模拟模板,我当然使用了宏.以下是它的外观示例:
#define _TEMPLATE_PAIR_STRUCT(T1, T2, TNAME, STRNAME) \
typedef struct { \
T1* first; \
T2* second; \
} STRNAME;
#define _TEMPLATE_PAIR_NEW(T1, T2, TNAME, STRNAME) \
STRNAME* TNAME##_new() \
{ \
STRNAME *new = malloc(sizeof( STRNAME )); \
new->first = malloc(sizeof(T1)); \
new->second = malloc(sizeof(T2)); \
return new; \
}
Run Code Online (Sandbox Code Playgroud)
如果我试图在多个源文件中使用此结构,我必须多次生成代码.显然,这会导致错误.
有没有办法解决这个问题,所以我可以在C中使用这些"模板"?
正如其他人所说,有几点要记住,主要是确保只有一个功能定义.
我不是特别喜欢这个解决方案,但在这里.
一个标题来统治它们(pair.h)
#ifndef TEMPLATE_PAIR
#define TEMPLATE_PAIR
#include <stdlib.h>
#define PAIR_NAME( T1, T2 ) T1##T2##NAME
#define PAIR_PTR_NAME( T1, T2 ) T1##T2##PTR_NAME
#define PAIR_CREATE( T1, T2) MAKE##T1##T2
#define PAIR_PTR_CREATE( T1, T2) MAKE_PTR##T1##T2
#define PAIR_PTR_FREE(T1, T2) FREE##T1##T2
#define PAIR_DEFINITION( T1, T2) \
typedef struct { \
T1 first; \
T2 second ; \
} PAIR_NAME(T1, T2)
#define PAIR_PTR_DEFINITION( T1, T2) \
typedef struct { \
T1* first; \
T2* second ; \
} PAIR_PTR_NAME(T1, T2)
#define MAKE_PAIR_DECLARE(T1, T2) PAIR_NAME(T1, T2) PAIR_CREATE(T1, T2) ( const T1& V1, const T2& V2 )
#define MAKE_PAIR_PTR_DECLARE(T1, T2) PAIR_PTR_NAME(T1, T2) PAIR_PTR_CREATE(T1, T2) ( const T1& V1, const T2& V2 )
#define PAIR_PTR_FREE_DECLARE(T1, T2) void PAIR_PTR_FREE(T1, T2) ( PAIR_PTR_NAME(T1, T2) & Pair )
#define MAKE_PAIR_SIGNATURE(T1, T2) PAIR_NAME(T1, T2) PAIR_CREATE(T1, T2) ( const T1& V1, const T2& V2 )
#define MAKE_PAIR_PTR_SIGNATURE(T1, T2) PAIR_PTR_NAME(T1, T2) PAIR_PTR_CREATE(T1, T2) ( const T1& V1, const T2& V2 )
#define FREE_PAIR_PTR_SIGNATURE(T1, T2) void PAIR_PTR_FREE(T1, T2) ( PAIR_PTR_NAME(T1, T2) & Pair )
#define MAKE_PAIR_DEFINE( T1, T2 ) \
MAKE_PAIR_SIGNATURE(T1, T2) { \
PAIR_NAME(T1, T2) pair; \
pair.first = V1; \
pair.second = V2; \
return pair; \
}
#define MAKE_PAIR_PTR_DEFINE( T1, T2 ) \
MAKE_PAIR_PTR_SIGNATURE(T1, T2) { \
PAIR_PTR_NAME(T1, T2) pair; \
pair.first = malloc( sizeof(T1) ); \
if ( pair.first != 0 ) *(pair.first) = V1; \
pair.second = malloc( sizeof( T2) ) ; \
if ( pair.second != 0 ) *(pair.second) = V2; \
return pair; \
}
#define PAIR_PTR_FREE_DEFINE( T1, T2 ) \
FREE_PAIR_PTR_SIGNATURE(T1, T2) { \
free( Pair.first ); \
free( Pair.second ); \
}
#endif
Run Code Online (Sandbox Code Playgroud)
一个标题带来全部(defs.h):
#ifndef DEFS_HEADER
#define DEFS_HEADER
#include "pair.h"
typedef int* pInt;
PAIR_DEFINITION( int, int );
PAIR_DEFINITION( int, double );
PAIR_DEFINITION( double, double );
PAIR_DEFINITION( pInt, pInt );
PAIR_DEFINITION( float, int );
PAIR_PTR_DEFINITION( int, int );
MAKE_PAIR_DECLARE( int, int );
MAKE_PAIR_DECLARE( int, double );
MAKE_PAIR_DECLARE( double, double );
MAKE_PAIR_DECLARE( pInt, pInt );
MAKE_PAIR_DECLARE( float, int );
MAKE_PAIR_PTR_DECLARE( int, int );
PAIR_PTR_FREE_DECLARE( int, int );
#endif
Run Code Online (Sandbox Code Playgroud)
在黑暗中绑定他们(impl.c):
#include "defs.h"
MAKE_PAIR_DEFINE( int, int );
MAKE_PAIR_DEFINE( int, double );
MAKE_PAIR_DEFINE( double, double );
MAKE_PAIR_DEFINE( pInt, pInt );
// manual "instantiation"
MAKE_PAIR_SIGNATURE( float, int )
{
PAIR_NAME( float, int ) local;
local.first = V1;
local.second = V2;
return local;
}
MAKE_PAIR_PTR_DEFINE( int, int );
PAIR_PTR_FREE_DEFINE( int, int );
Run Code Online (Sandbox Code Playgroud)
在阴影所在的主要土地上:
#include "defs.h"
int main(void)
{
PAIR_NAME(int, int) myPairInts;
PAIR_NAME( double, double) myPairDoubles;
PAIR_NAME( pInt, pInt) myPairPointers;
PAIR_NAME( float, int) myPairOther;
PAIR_PTR_NAME( int, int ) pairPtr;
myPairInts = PAIR_CREATE( int, int ) (1, 2);
myPairDoubles = PAIR_CREATE( double, double ) (5, 6.5);
myPairPointers = PAIR_CREATE( pInt, pInt) ( 0, 0 );
myPairOther = PAIR_CREATE( float, int) (1, 1);
pairPtr = PAIR_PTR_CREATE(int, int) (1, 2 );
PAIR_PTR_FREE(int, int) (pairPtr );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
PAIR_NAME创建一个包含值的结构,PAIR_PTR_NAME包含指向值的指针.PAIR_CREATE并PAIR_PTR_CREATE创建值并填充对内的数据.
您需要在"impl.c"中定义所有必要的组合.任何编译单元都可以#include "defs.h"使用这些对.
编辑 - 问题的答案:
"pair.h"仅包含宏,可以安全地用于任何库或程序.
重要的是你没有两次定义相同的功能.我也不会两次定义相同的结构.
你可以尽管做到以下几点: -以pair.h,defs.h中和impl.c因为它们上面,并将其建设成一个库(添加任何必要的__declspec(dllexport)和__declspec(dllimport) -然后你可以#include pair.h和defs.h并使用在程序中定义那里对- 如果你想使用新的对,(float, float)那么你需要添加一个新的defs_my_program.h和一个新的impl_my_program.c来声明和定义这些新对.的defs_my_program.h报头可以与被包括沿着defs.h所述库提供报头.
您仍然可以为每对获得一个声明和一个定义.唯一的"缺点"是你不能真正(安全地)即时使用对,它们需要集中化.
好吧,对于初学者来说,你要求std::pair而不是为了一个人.
注意,std::pair相当于PAIR_NAME,没有std::pair分配动态内存.
如果您不需要自动使用,则不需要任何新的专业化malloc.用这个例子pInt显示,你可以创建小号pair的(int, int*)或(int*, int).只是指针的值需要来自外部pair.
如果你真的想要一个pair的(int, int*),对于自动分配内存int*,你必须把它自己加入,如果你真的需要它.我希望你不会.
对于值的元组,一个不太理想的解决方案可能是使用paira pair和另一个元素.这将为您提供包含三个元素的结构.这样的事情可能可以通过宏观魔法来完成,减少你担心的指数增长.