简体   繁体   中英

C++ Custom Comparison Function with Template as Function Parameter

I'm trying to implement/use a comparator style interface like the one you would find in Java that would allow me to pass a generic comparator type to a function and use that to sort a data set.

This is because I need a variety of different comparison functions and I want be able to pass the one I need into the sort function.

Here's a code snippet of what I have so far and hopefully you can tell what I mean:

void Population::sort(const std::shared_ptr<Comparator<Solution>>& comparator)
{
    std::sort(data.begin(), data.end(), comparator.get());
}

And the comparator interface I've tried to implement

template <typename T> class Comparator : public std::binary_function<T,T,bool>
{
public:
    virtual ~Comparator ();
    virtual bool operator() ( const T &o1, const T &o2  ) = 0;
};

It's probably something obvious I'm doing wrong as I don't know a whole lot of C++.

Cheers!

Unless you explicitly need to change the comparison predicate at run-time I would opt to make the Population::sort function a template function:

struct Person
{
    std::vector<int> v;

    template<typename P>
    void sort(P& p)
    {
        std::sort(v.begin(), v.end(), p);
    }
};

This then gives you a wide range of options for your predicate. Such as:

bool mycompare(int a, int b)
{
    return a < b;
}

struct predicate
{
    bool operator()(int a, int b)
    {
        return a < b;
    }
};

struct myclass
{
    bool function(int a, int b)
    {
        return a < b;
        }
};

int main()
{

    Person p;

    // you can use a lambda
    p.sort([](int a, int b){return a < b;});
    // you can use a functor
    predicate pred;
    p.sort(pred);
    // you can use a free function
    p.sort(mycompare);
    // you can bind to a class member function
    myclass c;
    p.sort(std::bind(&myclass::function, &c, std::placeholders::_1, std::placeholders::_2));
    std::copy(p.v.begin(), p.v.end(), std::ostream_iterator<int>(std::cout));
}

Using template functions like this allows a lot of flexibility.

First: you should properly implement your comparator. Something like:

template <typename T>
struct Comparator : public std::binary_function<T,T,bool>
{
    bool operator()(const T& o1, const T& o2)
    {
        return o1 < o2;
    }
}

Second: you should put instance of your comparator to std::sort:

std::sort(data.begin(), data.end(), Comparator<Solution>());

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