8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

这个标题是 C 语言中 `_Generic` 的一个很好的用例吗?

Harshil Patanvadiya 1月前

18 0

我正在用 C 语言编写一个侵入式数据结构库。其中许多容器将共享功能。例如,将有许多容器提供正向和反向迭代。因此,我

我正在用 C 编写一个侵入式数据结构库。其中许多容器将共享功能。例如,将有许多容器提供正向和反向迭代。因此,我创建了一个标头,它将在所有容器中以宏的形式提供这些通用操作。这里只是正向迭代器。

#include "double_ended_priority_queue.h"
#include "ordered_map.h"
#include "realtime_ordered_map.h"

#define BEGIN(container_ptr)                                          \
    _Generic((container_ptr),                                         \
        double_ended_priority_queue *: depq_begin,                    \
        ordered_map *: om_begin,                                      \
        realtime_ordered_map *: rom_begin)(container_ptr)

#define NEXT(container_ptr, iter_elem_ptr)                            \
    _Generic((container_ptr),                                         \
        double_ended_priority_queue *: depq_next,                     \
        ordered_map *: om_next,                                       \
        realtime_ordered_map *: rom_next)((container_ptr),            \
                                          (iter_elem_ptr))

用法如下。

struct val
{
    int id;
    int val;
    ccc_depq_elem elem;
};

void
inorder_fill(int vals[], size_t size, double_ended_priority_queue *pq)
{
    if (depq_size(pq) != size)
    {
        return;
    }
    size_t i = 0;
    for (struct val *e = BEGIN(pq); e && i < size; e = NEXT(pq, &e->elem))
    {
        vals[i++] = e->val;
    }
}

这看起来不错,而且这种功能可以扩展到许多其他操作(emplace、Rust 的 Entry API、范围等)。但是,我必须在 _Generic 文件顶部的列表中包含所有容器的标头。否则,当用户包含文件时, generics.h 未包含的 _Generic 类型案例的类型都是未知的

随着更多容器共享这些功能,文件 generics.h 中包含的内容数量 _Generic 使用这种方法没有运行时开销,但我似乎用这种方法造成了巨大的编译时间膨胀。

  • 我是否误解了一个很好的用例 _Generic
  • C 中还有其他泛型方法吗?还是我试图解决不存在的问题,并且每个容器自己提供此功能就可以了?
帖子版权声明 1、本帖标题:这个标题是 C 语言中 `_Generic` 的一个很好的用例吗?
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Harshil Patanvadiya在本站《c》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 说实话,我从未发现 C 中的泛型有用。我看不到任何用处。难以阅读,容易出错,并且难以调试。我会避免使用它们。

  • 我想说代码非常好。

    或许,不需要使用一些神秘的 BEGIN / NEXT 宏,而是考虑将整个循环放在一个函数中,以使代码更具可读性。

    如果函数已经存在并且无法修改,则考虑使用包装函数(将被内联/优化)。

    也就是说,创建一个类似的宏 container_iterate() ,该宏使用检查容器的类型 _Generic ,然后调用例如 depq_iterate 包含 for 循环和对 depq_begin / depq_next .

    至于在添加更多类型时维护大量宏的问题——总会有 X 宏,它们除其他外还可用于生成 _Generic 关联列表,甚至函数模板。它们以牺牲可读性为代价来提高可维护性。但也许这是另一个问题的内容。

返回
作者最近主题: