3

I need to sort characters of a string and need to have lower letters appear first. For example, "acDbA" would become "abcAD" after sorting.

The code below is what I came up with:

bool compare(const char& c1, const char& c2) {
    if (c1 >= 'A' && c1 <= 'Z' && c2 >= 'a' && c2 <= 'z') return false;
    if (c2 >= 'A' && c2 <= 'Z' && c1 >= 'a' && c1 <= 'z') return true;
    return c1<c2;
}
void sortLetters(string &letters) {
    sort(letters.begin(), letters.end(), compare);
}

However in Visual Studio I got:

'sort': no matching overloaded function found   
'SortLetters::compare': non-standard syntax; use '&' to create a pointer to member  
'void std::sort(_RanIt,_RanIt)': expects 2 arguments - 3 provided   

How should I create custom compare function for sorting a string, I couldn't seem to find examples online with string sorting.

4
  • Could you please state the reason for down vote, I couldn't find an related example online? Commented Jul 4, 2017 at 20:14
  • 1
    Ok I got it.. if I put the above functions outside the class it works. It didn't occur to me that those functions are member functions that is the issue. Commented Jul 4, 2017 at 20:34
  • Yes, the error message gives it away: "use & to create a pointer to member". FWIW, you can also make it a static method. Commented Jul 4, 2017 at 20:42
  • @zneak Yes, I think just by marking the member function "compare" as static then it works. Commented Jul 4, 2017 at 20:45

2 Answers 2

2

The above code does compile just fine when using a free function. I your case, you're using a object's method, which isn't simply callable.

You could pass a functor object or a lambda object too. By the way, since std::sort is a function template, it doesn't matter what the exact parameters of the comparator are. The only thing that matters that it is able to take the both values and return something that can be converted to bool.

Sign up to request clarification or add additional context in comments.

4 Comments

No, you don't have to pass a function pointer. The OP's code compiles fine on Visual Studio 2015. I suspect he's using an older version of Visual Studio.
Right, a recent gcc doesn't show any error either.
@TheTechel thanks for your help. the compare function looks more succinct. But either adding the address symbol or not doesn't change the functionality.
I re-read your question and notices that the compiler complains about a pointer to a method.
1

The code below works, only change is the compare member function is now marked "static":

class SortLetters {
public:
    static bool compare(const char& c1, const char& c2) {
        if (c1 >= 'A' && c1 <= 'Z' && c2 >= 'a' && c2 <= 'z') return false;
        if (c2 >= 'A' && c2 <= 'Z' && c1 >= 'a' && c1 <= 'z') return true;
        return c1<c2;
    }
    void sortLetters(string &letters) {
        sort(letters.begin(), letters.end(), compare);
    }
};

2 Comments

To clarify why this is that way, if you had bool compare(const char& c1, const char& c2); without the static, it's a lot like as if you had a free function bool compare(SortLetters&, const char& c1, const char& c2). By marking it as static, you remove that implicit SortLetters& parameter. The implicit parameter is because you can do something like this: SortLetters sl; sl.compare(c1, c2), and inside compare, you can access member variables of sl.
:) It makes sense that if it's a non-static member function, it will have access to all object-specific states and this is not desired when it's intended to be used as a generic function.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.