代码之家  ›  专栏  ›  技术社区  ›  The Matt

C++安全有效地铸造STD::弱序到int

  •  1
  • The Matt  · 技术社区  · 5 年前

    C++ 20引入了一种新的比较类型: std::weak_ordering .

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

    但是,一些旧函数使用 int 为了类似的目的。例如 qsort ,它使用签名

    int compar (const void* p1, const void* p2);
    

    std::weak_ordering 用于函数中,例如 qsort

    下面是一个例子:

    #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_cast int8_t 类型确实有效,但我不确定这是否是可移植的。

    int equivalent_cmp = *(int8_t *)&cmp;
    

    或等效地,

    int equivalent_cmp = *reinterpret_cast<int8_t*>(&cmp);
    

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

        int equivalent_cmp = (a > b) - (a < b);
    

        int equivalent_cmp;
        if (cmp < 0)       equivalent_cmp = -1;
        else if (cmp == 0) equivalent_cmp =  0;
        else               equivalent_cmp =  1;
    

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

    0 回复  |  直到 5 年前
        1
  •  4
  •   Jeff Garrett    5 年前

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

    不。

    如果你需要它,最好的办法就是写一些类似于你最后一段的东西

    constexpr int ordering_as_int(std::weak_ordering cmp) noexcept {
        return (cmp < 0) ? -1 : ((cmp == 0) ? 0 : 1);
    }
    
        2
  •  3
  •   Barry    5 年前

    std::weak_ordering int qsort ?

    快速排序 ,使用 std::sort 无论如何,它会表现得更好。


    std::弱顺序 必须有一些整型成员,C++ 20确实有一个机制来把它拔出来: std::bit_cast :

    static_assert(std::bit_cast<int8_t>(0 <=> 1) == -1);
    

    int8_t std::strong_ordering ). 这是对我的限制 bit_cast ,所以如果实现实际存储 内景 国际贸易


    请注意 weak_ordering strong_ordering 将只实现为存储一个整数(尽管不是 内景 如标准所示), partial_ordering 和一个 bool

    推荐文章