gpt4 book ai didi

c++ - C++ 中的 C++ 模板

转载 作者:太空狗 更新时间:2023-10-29 23:52:15 25 4
gpt4 key购买 nike


我正在尝试从 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; \
}

如果我试图在多个源文件中使用这个结构,我必须多次生成代码。显然,这会导致错误。

有没有办法解决这个问题,以便我可以在 C 中使用这些"template"?

最佳答案

正如其他人所说,有几点需要牢记,主要是确保只有一个函数定义。

我不是特别喜欢这个解决方案,但就是这样。

一个标题来统治它们(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

一个头文件把它们都带进来(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

然后在黑暗中绑定(bind)它们(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 );

在阴影所在的主之地:

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

PAIR_NAME 创建一个包含值的结构,PAIR_PTR_NAME 包含指向值的指针。 PAIR_CREATEPAIR_PTR_CREATE 创建值并在对中填充数据。

您需要在“impl.c”中定义所有必要的组合。任何编译单元都可以#include "defs.h" 并使用对。

编辑 - 问题的答案:

  1. “当我在库或类似的东西中使用它一次,然后在同时使用该库和"template"对的程序中再次使用时,这不会造成麻烦吗?”

“pair.h”只包含宏,可以在任何库或程序中安全使用。

重要的是您不要定义同一个函数两次。我也不会两次定义相同的结构。

您可以执行以下操作:- 将上面的 pair.h、defs.h 和 impl.c 构建到一个库中(添加任何必要的 __declspec(dllexport)__declspec(dllimport)- 然后你可以 #include pair.hdefs.h 并使用程序中定义的对- 如果你想使用新的对,比如说 (float, float) 你需要添加一个新的 defs_my_program.h 和一个新的 impl_my_program.c 来声明和定义这些新对。 defs_my_program.h header 可以与库提供的 defs.h header 一起包含在内。

对于每一对,您仍然会得到一个声明和一个定义。唯一的“缺点”是您不能真正(安全地)即时使用对,它们需要集中处理。

  1. “您选择类型和函数名称的方式确实带来了一些问题。您将一对包含两个值,一个包含两个指针。您还需要对包含一个指针和一个指针的一对进行专门化值,以及具有一个值和一个指针的一对。所以我已经有 4 对案例了。将其用于三元组或更高的元组,我将不得不实现 2^n 个案例。”

好吧,对于初学者来说,您要求的是 std::pair 而不是双元组。

请注意,std::pair 等同于PAIR_NAME,没有分配动态内存的std::pair

如果您不需要自动使用 malloc,则不需要任何新的特化。 pInt 的示例表明您可以创建 (int, int*)(int*, int)< 的 /。只是指针的需要来自pair之外。

如果你真的想要一个 pair(int, int*) 自动为 int* 分配内存,你必须添加如果您确实需要它,请自己使用。我希望你不会。

对于值元组,一个不太理想的解决方案可能是使用 pair 中的 pair 和另一个元素。这将为您提供一个包含三个元素的结构。类似的事情可能可以通过宏观魔法来完成,减少您担心的指数增长。

关于c++ - C++ 中的 C++ 模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16628777/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com