我可以在C中获得“宏多态性”吗?
发布时间:2020-12-16 10:36:36 所属栏目:百科 来源:网络整理
导读:我所追求的多态性类型是这样的: 假设我有一个名为draw()的宏,我有2个结构,一个叫做圆圈,另一个叫做方形.有可能以某种方式做这样的事情: #define draw() // can I get the text that's behind the macro?//then maybe,with _Generic achieve this?void draw
我所追求的多态性类型是这样的:
假设我有一个名为draw()的宏,我有2个结构,一个叫做圆圈,另一个叫做方形.有可能以某种方式做这样的事情: #define draw() // can I get the text that's behind the macro? //then maybe,with _Generic achieve this? void draw_circle(struct circle); void draw_square(struct square); struct circle c; struct square s; c.draw();//draw is a macro. this time it is supposed to expand to draw_circle(c); s.draw();//supposed to expand to draw_square(s); EDIT_1:在阅读完答案之后,这是我到目前为止所做的. //raw_array.h #pragma once #include <stdint.h> #include <stdlib.h> #define byte uint8_t #define _GET_OVERRIDE(_1,_2,_3,NAME,...) NAME /*#define init_impl(...) _GET_OVERRIDE(__VA_ARGS__, init_impl3,init_impl2,init_impl1)(__VA_ARGS__) #define init( name,... ) (raw_array * (name); init_impl( (name),__VA_ARGS__))*/ #define array_init_impl(...) _GET_OVERRIDE(__VA_ARGS__,init_array_impl3,init_array_impl2,init_array_impl1)(__VA_ARGS__) ///<summary>creates a variable of type raw_array with name as an identifier,and initializes based on the parameters</summary> #define RAW_ARRAY( name,... ) raw_array (name); array_init_impl( (&name),__VA_ARGS__) typedef struct indexable_memory_block_struct { raw_array * _self; byte * bytes; size_t element_size; size_t number_of_elements; } raw_array; ///<summary>starts the an empty raw_array. only element_size is set.</summary> ///<param name=r_arr>the raw_array to be initialized</param> ///<param name=element_size>the size of the elements in this raw_array</param> void init_impl1 ( raw_array * r_arr,size_t element_size ) { r_arr = malloc ( sizeof ( raw_array ) ); r_arr->element_size = element_size; r_arr->number_of_elements = 0; r_arr->bytes = NULL; r_arr->_self = r_arr; } ///<summary> ///starts the raw_array an empty. byte with its bytes allocated ///to their default value (0). ///</summary> ///<param name=r_arr>the raw_array to be initialized</param> ///<param name=element_size>the size of the elements in this raw_array</param> ///<param name=number_of_elements>the number of elements in the array</param> void init_impl2 ( raw_array * r_arr,size_t element_size,size_t number_of_elements ) { r_arr = malloc ( sizeof ( raw_array ) ); r_arr->element_size = element_size; r_arr->number_of_elements = number_of_elements; r_arr->bytes = calloc ( number_of_elements,element_size ); r_arr->_self = r_arr; } ///<summary> ///starts the raw_array copying its contents from a normal array. ///</summary> ///<param name=r_arr>the raw_array to be initialized</param> ///<param name=arr>the normal C array whose contents will be copied to this raw_array</param> ///<param name=element_size>the size of the elements in this raw_array</param> ///<param name=number_of_elements>the number of elements in the array</param> void init_impl3 ( raw_array * r_arr,const void * const arr,size_t size_of_element,size_t number_of_elements ) { r_arr->bytes = malloc ( size_of_element * number_of_elements ); memcpy ( r_arr->bytes,arr,size_of_element * number_of_elements ); r_arr->element_size = size_of_element; r_arr->number_of_elements = number_of_elements; r_arr->_self = r_arr; } 还有其他部分,但这些是目前移植到这种新语法的部分.现在主要: int main ( int argc,char * argv[] ) { int data[30]; //line bellow has a compilation error: *expected a ')'* init ( r_arr,data,sizeof ( int ),30 ); } 什么意思预期’)’ EDIT_2:发现严重错误,将修复它并再次编辑. Visual Studio正在更新(12GB ……)所以我目前无法构建任何东西. [迷你编辑]:我猜我至少修正了粗错误. [迷你编辑]我的代码中另一个非常奇怪的错误,我将名称标记字符串化,是吗?!现在纠正了. EDIT_3:已经睡觉并且VS再次运行,我修复了宏,将编辑它们并注释掉错误的代码.现在我需要circle.draw()行为……任何想法? 解决方法
除了@LirooPierre的方法,你还可以使用C11 Generics.是的你没听错,C现在有仿制药.
考虑这个例子: #include <stdio.h> #define draw(X) _Generic((X), struct circle: draw_circle, struct square: draw_square )(X) struct circle{}; struct square{}; void draw_circle(struct circle a) { printf("Drawing a circlen"); } void draw_square(struct square a) { printf("Drawing a squaren"); } int main(void) { struct square a; draw(a); // "Drawing a square" } 但即使它应该是便携式的,但遗憾的是它不是. M $编译器没有实现它们,但是clang和gcc这样做. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |