C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了我可以在C中获得“宏多态性”吗?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我所追求的多态性类型是这样的

假设我有一个名为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 );
}

什么意思预期’)’
你们可以查看宏语法吗?
关于_Generic,我今天学到了它,如果它有用的话,我肯定会使用它.

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 circle\n");
}
void draw_square(struct square a)
{
    printf("Drawing a square\n");
}

int main(void)
{
    struct square a;
    draw(a);  // "Drawing a square"
}

但即使它应该是便携式的,但遗憾的是它不是. M $编译器没有实现它们,但是clang和gcc这样做.

大佬总结

以上是大佬教程为你收集整理的我可以在C中获得“宏多态性”吗?全部内容,希望文章能够帮你解决我可以在C中获得“宏多态性”吗?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。