2

I have implemented my own container:

template<typename T>
class MyContainer
{
    // body where in some point 2 elements of collection are compared (-1, 0 and 1 possible comparison results)
};

What I want to do is add support of function objects, just like in std::set, where it is possible to do function object like this:

struct Comparator
{
    bool operator()(const char* s1, const char* s2) const
    {
        return strcmp(s1, s2) < 0;
    }
};

and then pass it as set parameter:

std::set<const char*, Comparator> SomeSet;

I'm not every-day C++ programmer, so I need help to achieve that. What must I do in order to add support to this? Must I create field in MyContainer in order to store function object in it to use it in my sorting methods inside container?

Przemysław Kalita
  • 1,977
  • 3
  • 18
  • 28
  • 1
    Your thought of what to do is correct... have you tried it out? – David Dec 01 '13 at 11:17
  • Usually it's done as functor template parameter with a default class given. – πάντα ῥεῖ Dec 01 '13 at 11:17
  • 1
    One of my problems is that I don't know how to handle type-compatibility between type passed to container and operator () in Comparator. I'm not very good at templates. – Przemysław Kalita Dec 01 '13 at 11:18
  • Just by calling the function. Compilation will fail if someone tries to pass a class that doesn't support the call operator. You could also add a static check for the `Comparator`class. – πάντα ῥεῖ Dec 01 '13 at 11:20
  • Another problem is how to specify default Comparer if user did not pass anything? And how to properly compare 2 objects of unknown type in this comparer? – Przemysław Kalita Dec 01 '13 at 11:29
  • 1
    @PrzemysławKalita: You can use the `std::less<>` template provided in the standard library. Look at e.g. `std::set`. It uses it too. – yzt Dec 01 '13 at 11:43

1 Answers1

0

I resolved it by adding default template value, and defining default comparing class:

template<typename T, class Compare = DefaultTreeOrder<T>>
class MyContainer
{
    private:
        Compare compare;
    public:
        MyContainer()
        {
            compare = Compare();
        }
};

where DefaultTreeOrder is:

template<typename T>
class DefaultTreeOrder 
{
    public:
        int operator()(T value1, T value2)
        {
            less<T> l;
            greater<T> g;

            if(l(value1, value2))
            {
               return 1;
            }
            else if(g(value1, value2))
            {
                return -1;
            }

            return 0;
        } 
};
Przemysław Kalita
  • 1,977
  • 3
  • 18
  • 28