views:

77

answers:

2

Regarding the following C++ code,

LengthAlphabeticalSort lengthAlphabeticalSort;
outputList.sort(lengthAlphabeticalSort); // causes borland 8092 error, guaranteed stable_sort.

class LengthAlphabeticalSort
{
    public:
        bool operator() (std::string str1, std::string str2)
        {
            if(str1.length() < str2.length())
                return true;
            else
                return false;
        }
};

I get a warning when compiling with the borland compiler:

Warning W8092 worder.cpp 138: template argument _Pr3 passed to 'sort' is not an iterator: random iterator required in function Worder::CommonWords(const Worder &) const Turbo Incremental Link 5.69 Copyright (c) 1997-2005 Borland

Can anybody tell me how to fix this problem? It compiles cleanly with VS2010 and gnu

+1  A: 

Well, the sort member function on a std::list does take a binary functor like yours, so from looking at your posted code, I'd say your compiler is wrong.

However, the error message you posted puzzles me:

random iterator required in function Worder::CommonWords(const Worder &) const

Why is it saying that a random iterator is required in CommonWords? Is CommonWords the function from which sort is called?

jalf
Yes, the sort is called in CommonWords.
aCuria
I guess its a compiler error, pity nobody has a more definitive answer.
aCuria
+1  A: 

Personally, I find the name LengthAlphabeticalSort confusing because the sort is purely by length, not by something alphabetical. Also, you should pass strings by reference-to-const, and the if-else is superfluous:

struct ByLength
{
    bool operator()(const std::string& a, const std::string& b)
    {
        return a.length() < b.length();
    }
};

The initial list is guaranteed to be in alphabetical order.

Does that mean you are sorting twice, first alphabetical, then by length? I think it's better practice to sort only once with an adequate predicate:

struct FirstByLengthThenAlphabetical
{
    bool operator()(const std::string& a, const std::string& b)
    {
        if (a.length() < b.length()) return true;
        if (b.length() < a.length()) return false;
        return a < b;
    }
};
FredOverflow
The initial list is guaranteed to be in alphabetical order. Hence, as list.sort() is guaranteed to be a stable sort, just sorting by length will give a sort that is by length and then, if the same length, in alphabetical order hence the naming convention.passing by reference and the superfluous if-else is something I overlooked. +1
aCuria
@aCuria: I have updated my post.
FredOverflow
@Fred, theres a good reason why its already alphabetical. I am calling set_intersection on two sets and outputting the result to a list. Hence the list is always alphabetical in the first place.
aCuria
@aCuria: Okay, nevermind then.
FredOverflow