如何将 const void* 强制转换为结构元素?

Posted

技术标签:

【中文标题】如何将 const void* 强制转换为结构元素?【英文标题】:How can I cast a const void* to a struct element? 【发布时间】:2016-09-24 18:59:23 【问题描述】:

我的比较函数可以在 qsort() 中使用,如下所示:

int compar(const void *p, const void *q)
    interval a,b;

    *p = (interval)a
    *q = (interval)b;

    if(a.extrem[1] < b.extrem[0])
        return -1;
    if(b.extrem[1] < a.extrem[0] )
        return 1;

    return 0;

我的结构如下:

typedef struct interval
    double extrem[2];
     interval;

我在函数比较中尝试了许多“强制转换”变体,但都失败了。我的问题很明显,如何将 const void* 强制转换为我的结构元素?我知道这似乎是一个非常基本的问题,但我在任何地方都找不到明确的答案,我也是新手。任何帮助都将不胜感激。

【问题讨论】:

a = *(interval*)p; 可能就是你的意思。 您不能转换为 struct 类型或从 struct 类型转换。您可以将void* 转换为指针类型或从指针类型转换。 (事实上​​,转换可以隐式完成,无需强制转换。) 你到底为什么要这样做?丢弃参数中的所有类型信息,然后将数据视为特定类型是一种可怕的做法。如果有人用指向不同类型的指针调用它(没有什么能阻止任何人这样做!)这将导致各种问题。为什么不直接采用实际结构类型的 const ref 参数? @adam10603 linux.die.net/man/3/qsort @chux 这似乎是考虑重叠间隔相等的间隔排序。这是一个无效的排序比较器,因为您可以有compar(a, b) == 0 &amp;&amp; compare(b, c) == 0compar(a, c) == -1 的间隔。 【参考方案1】:

你很亲密……

typedef struct interval 
  double extrem[2];
 interval;

int compar(const void *p, const void *q) 
  const interval *a = p, *b = q;

  if(a->extrem[1] < b->extrem[0])
    return -1;
  if(b->extrem[1] < a->extrem[0])
    return 1;
  return 0;

顺便说一句,没有一个演员,这将在gcc -Wall.下完全干净

更新... Tavian 提出了一个很好的观点,这不是传递顺序,所以您的集合在技术上具有 no partial order. 但根据您的数据和您的目标,qsort 可能会返回一个有用的结果。

【讨论】:

【参考方案2】:

qsort() 函数将使用指向元素的指针调用您的回调。

假设数组是interval 的实际数组,而不是区间指针之一,你会这样做:

static int interval_compare(const void *a, const void *b)

  const interval *ia = a, *ib = b;

  if(ia->extrem[1] < ib->extrem[0]) return -1;
  return ib->extrem[1] > ia->extrem[0];

我不理解 extrem 索引,但这是您使用的。将void * 转换为更具体的类型时不需要强制转换。见this answer。

【讨论】:

这是一个一维问题,考虑到任何重叠都是相等的,并且不等式是有序的。顺便说一句,正如现在所写的那样,它不会编译。 @DigitalRoss 谢谢,已修复。

以上是关于如何将 const void* 强制转换为结构元素?的主要内容,如果未能解决你的问题,请参考以下文章

constexpr 和使用重新解释强制转换的静态 const void 指针的初始化,哪个编译器是正确的?

将 const void* 转换为 const int*

C++|项目开发—强制类型转换回顾

C++|项目开发—强制类型转换回顾

为啥不能将不完整的类型强制转换为 void?

c ++将void *转换为int错误