首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++安全有效地将std::weak_ordering转换为int

C++安全有效地将std::weak_ordering转换为int
EN

Stack Overflow用户
提问于 2021-02-13 01:15:18
回答 2查看 349关注 0票数 2

C++20正在引入一种新的比较类型:定序

它允许表示小于、等于或大于。

然而,一些较旧的函数使用int来实现类似的目的。例如Q排序,它使用签名

代码语言:javascript
复制
int compar (const void* p1, const void* p2);

如何将std::weak_ordering转换为int,以便在qsort之类的函数中使用

下面是一个例子:

代码语言:javascript
复制
#include <compare>
#include <iostream>

int main() {
    long a = 2354, b = 1234;
    std::weak_ordering cmp = a <=> b;
    
    if (cmp > 0)  std::cout << "a is greater than b" << std::endl;
    if (cmp == 0) std::cout << "a is equal to b" << std::endl;
    if (cmp < 0)  std::cout << "a is less than b" << std::endl;

    int equivalent_cmp = cmp; // errors
}

在测试中,我注意到使用reinterpret_castint8_t类型确实有效,但我不确定这是否是可移植的。

代码语言:javascript
复制
int equivalent_cmp = *(int8_t *)&cmp;

或者同等的,

代码语言:javascript
复制
int equivalent_cmp = *reinterpret_cast<int8_t*>(&cmp);

这安全吗?

此外,还有其他一些解决方案可以工作,但与这种“不安全”方法相比效率低下。所有这些都会比上面的解决方案慢。

代码语言:javascript
复制
    int equivalent_cmp = (a > b) - (a < b);

代码语言:javascript
复制
    int equivalent_cmp;
    if (cmp < 0)       equivalent_cmp = -1;
    else if (cmp == 0) equivalent_cmp =  0;
    else               equivalent_cmp =  1;

是否有更好的解决方案可以保证有效?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-02-13 17:16:23

是否有更好的解决方案可以保证有效?

不是的。

标准没有指定排序类的内容或表示形式。巴里的答案是基于合理的假设,这些假设很可能站得住脚,但它们并不能得到保证。

如果你需要的话,你最好的办法是写一些类似你最后的片段。

代码语言:javascript
复制
constexpr int ordering_as_int(std::weak_ordering cmp) noexcept {
    return (cmp < 0) ? -1 : ((cmp == 0) ? 0 : 1);
}
票数 4
EN

Stack Overflow用户

发布于 2021-02-13 15:11:41

如何将std::weak_ordering转换为int,以便在qsort之类的函数中使用?

简单的答案是:不要使用qsort,使用std::sort,反正效果会更好。

尽管如此,我们知道std::weak_ordering必须有一些完整的类型成员,而C++20确实提供了一种机制来提取它:std::bit_cast

代码语言:javascript
复制
static_assert(std::bit_cast<int8_t>(0 <=> 1) == -1);

规则是,您要转换到的类型(在本例中为int8_t)必须与您要转换的类型相同(在本例中为std::strong_ordering)。这是对bit_cast的一个约束,所以它是安全的--如果实现实际上存储了一个int而不是一个int8_t,这将不会编译。

因此,更广泛地说,您需要编写一个简短的元程序来确定要转换到的正确的有符号整数类型。

请注意,虽然weak_orderingstrong_ordering只是作为一个整数来实现(尽管不是标准中所示的int ),但partial_ordering可能不会实现为存储intbool --它很可能仍然是作为一个整数实现的。所以这个把戏行不通。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66181029

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档