简体   繁体   中英

Function that returns max element of an array of different types

I have couple of compare function that go something like this:

int greater_than_int(const void *a, const void *b) {
    if (*(int *)a > *(int *)b) return 1;
    return 0;
}

and a max function that goes like this:

const void* max(const void *base, size_t members, size_t size,
              int (*compar)(const void *, const void *)) {

char *base_ptr = (char *) base;
char max = *base_ptr;
for(int i = 1; i < nmemb; i++) {
    if (compar(&(*(base_ptr + i*size)), &max) != 0) {
        max = *(base_ptr + i*size);
    }
}
return &max;

}

When I try to run this function with greater_than_int I get nonsense results and since I'm still pretty new with C++ I'm not sure why. Any help would be appreciated.

Edit: I've changed some things to my code but now it always returns max as 0. Still trying to figure out why, I appreciate all the people saying that this isn't the best way to do this but, unfortunately, this is the way that I have to do this.

Since you're forced to work with those function signatures, here's one way of dealing with them.

// I suggest changing this to `bool`, but you can leave it as `int` if you must
bool greater_than_int(const void *a, const void *b) {
    // no need for `if(...)` - just return the result of the comparison
    return *static_cast<const int*>(a) > *static_cast<const int*>(b);
}

Then, the actual max function has some problems where you define max as a char and not a pointer etc. max can be left as a const void* since you don't need to perform any pointer arithmetics with it. I'm using base as the pointer to the maximum element below instead.

#include <iterator> // std::next, std::advance

const void* max(const void *base, size_t nmemb, size_t size,
                bool (*compar)(const void*, const void*))   // note: bool here too
{
    if(nmemb) {
        // no need to cast away const:
        auto current = static_cast<const char*>(base);
        auto end = std::next(current, nmemb * size);

        for(std::advance(current, size); current != end; 
            std::advance(current, size))
        {
            if(compar(current, base)) base = current;
        }
    }
    return base;
}

Demo

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.

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