简体   繁体   English

在 std::qsort 的比较函数中处理错误条件

[英]Handling an error condition in the compare function of std::qsort

I am trying to figure out a way for qsort to throw an exception or indicate an error condition if the compare function finds that the elements are, for some reason, invalid for sorting.我试图找出一种方法,如果比较函数发现元素由于某种原因对排序无效,则qsort会抛出异常或指示错误条件。

For example, in this compare function, I need to indicate an error condition that my sorting is invalid if the return value of some_function is 5 .例如,在这个比较函数中,如果some_function的返回值为5 ,我需要指示我的排序无效的错误条件。

How should I modify my compare function?我应该如何修改我的比较功能?

int compare (const void * a, const void * b)
{
  int ret1 = some_func(a);
  int ret2 = some_func(b):
  return ( ret1 - ret2 );
}

I am dealing with a legacy code base so I'm not in the position to use std::sort and due to the nature of the implementation calling some_func before hand might also involve huge amount of changes so I'm looking to understand if a workaround is possible.我正在处理遗留代码库,因此我无法使用std::sort并且由于实现的性质,事先调用some_func也可能涉及大量更改,因此我希望了解是否解决方法是可能的。

Throwing an exception is potentially expensive, so you probably want to return an error condition.抛出异常可能会很昂贵,因此您可能希望返回错误条件。 However, doing either approach inside the compare function is needlessly expensive in this case, since you would be doing the check multiple times for every element.但是,在这种情况下,在compare函数中执行任何一种方法都是不必要的昂贵,因为您将对每个元素进行多次检查。 Instead, you could just check for the error condition before calling qsort which is much more efficient:相反,您可以调用更有效的qsort之前检查错误条件:

auto ok = std::none_of(/* range */, /* predicate */);

if (ok)
  std::qsort(/* ... */)
else
  // report error

C++ allows you to throw whatever you need, not only exceptions but also other types, you could do something like throw an int if it suits your purposes and catch where you call the function with a try-catch block. C++ 允许你抛出任何你需要的东西,不仅是异常,还有其他类型,如果它适合你的目的,你可以做一些像 throw an int事情,并用try-catchtry-catch调用函数try-catch

For what you need I think you can use STL exception library:对于您所需要的,我认为您可以使用 STL 异常库:

Demostrative example :示范性例子

#include <iostream>
#include <exception>

int count = 0;

int compare(const void *a, const void *b)
{  
    int ret1 = *(int*)a > *(int*)b;
    
    if (++count == 5) //throws exception when count reaches 5
        throw std::invalid_argument("Argument is not sortable");
    //you could throw count by simply using throw count

    return ret1;
}

int main()
{
    int x[]{2,1,3,5,6,1,7,2,5,3};
    try
    {
        //will sort until exception is thrown
        qsort(x, sizeof x / sizeof *x, sizeof(int), compare);
    }
    catch (const std::exception& e)
    {
        std::cout << e.what() << std::endl; //print exception in the console
        //handle the exception here
        //if you were to throw count you could cach it with
        //catch (int &e)
    }

    //note that the values were sorted until the exception was thrown
    for (int i = 0; i < sizeof x / sizeof *x; i++){
        std::cout << x[i] << " ";
    }
}

Output:输出:

Argument is not sortable
1 2 3 5 6 1 7 2 5 3  
        ^
     sorting 
     stopped 
      here

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM