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.
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
.
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.
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. Instead, you could just check for the error condition before calling qsort
which is much more efficient:
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.
For what you need I think you can use STL exception library:
#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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.