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

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

我正在尝试找出一种方法,让 qsort 在比较函数发现元素由于某种原因对排序无效时抛出异常或指示错误条件。

例如,在这个比较函数中,如果some_function的return值为5,我需要指示一个错误条件,即我的排序无效.

我应该如何修改我的比较功能?

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

我正在处理遗留代码库,所以我无法使用 std::sort,并且由于实施的性质,事先调用 some_func 也可能涉及大量的变化,所以我想了解是否有可能的解决方法。

抛出异常可能代价高昂,因此您可能想要 return 一个错误条件。但是,在这种情况下,在 compare 函数中执行任何一种方法都不必要地昂贵,因为您将对每个元素进行多次检查。相反,您可以在 调用 qsort 之前检查错误条件 ,这样效率更高:

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

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

C++ 允许你抛出任何你需要的东西,不仅是异常,还有其他类型,你可以做一些事情,比如抛出一个 int 如果它适合你的目的,并在你调用函数的地方用 try-catch块。

对于你需要的东西,我认为你可以使用 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] << " ";
    }
}

输出:

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