Question

Just idly curious why the compare function for stl::sort can't be a static member?

I have a small little helper class foo that is declared and defined in a header, but now I have to create a foo.cpp file for the implementation of cmp() so it isn't multiply defined.

I also have to think of a suitably decorated name so fooCmp() doesn't clash with any other cmp().

Because it has no access to any member variables any compare operation that needs access to some other value (eg. sort by distance from foo.bar) needs the complex bind2nd call.

Was it helpful?

Solution

I am not sure what you are complaining about:

std::sort(begin,end)        // use operator<
std::sort(begin,end,order)  // Where order is a functor

So order can be:

  • A function
  • A static member function
  • Or an object that behaves like a function.

The following works for me:

class X
{
    public: static bool diff(X const& lhs,X const& rhs) { return true;}
};

int main()
{
    std::vector<X>   a;

    std::sort(a.begin(),a.end(),&X::diff);
}

But if the class has some natural ordering then why not just define the operator< for the class. This will allow you the access to the members and will behave nicely for most of the standard containers/algorithms that need to define an ordering.

class X
{
    public: bool operator<(X const& rhs) const   {  return true;}
};
int main()
{
    std::vector<X>   a;

    std::sort(a.begin(),a.end());
}

OTHER TIPS

If you're concerned with a multiply defined compare function, try declaring the function with static linkage. Then the scope of the function does not extend past the compilation unit where it is found.

That said, your compare "function" need not be a function at all, but can instead be a function object. A function object is very much like a function but is implemented as an operator() that takes the appropriate parameters within a regular class. Since it's a regular class, you can pass constructor parameters to the class.

Here is a simple example:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class comparator {
public:
    bool operator()(int a, int b) {
        return a < b;
    }
};

int main(int, char *[])
{
    vector<int> a;
    a.push_back(1);
    a.push_back(3);
    a.push_back(2);
    sort(a.begin(), a.end(), comparator());
    cout << a << endl;
}

actually sounds like the function was declared in the class, defined in the header but outside the class without inline linkage

ie something like:

class foo{
public:
   static bool compare(const foo& lhs,const foo& rhs);
   ...
};
bool foo::compare(const foo& lhs,const foo& rhs){
   ...
} 

instead of

class foo{
public:
   static bool compare(const foo& lhs,const foo& rhs);
   ...
};
inline bool foo::compare(const foo& lhs,const foo& rhs){
   ...
} 

the first of which will cause the function to be defined in every compilation unit that

#includes "foo.h"
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top