1

When I call my build function from my code below, I get the following compile errors:

error C3867: 'SuffixArray::cmp': function call missing argument list; use '&SuffixArray::cmp' to create a pointer to member
error C2780: 'void std::sort(_RanIt,_RanIt)' : expects 2 arguments - 3 provided

This is my code:

class A{
private:
    std::string text;
    std::vector<int> array;

    bool cmp(int a, int b) {
        return std::lexicographical_compare(text.begin() + a, text.end(),
                                            text.begin() + b, text.end());
    }

    void build(const std::string &str, std::vector<int> &vec) {

        // Some vector values actions.

        std::sort(vec.begin(), vec.end(), cmp);
    }
};

What's wrong here? I'm using the Visual C++ compiler.

2 Answers 2

4

Your comparison function A::cmp is a non-static member of A. Thus, it takes three arguments: in addition to the two arguments explicitly declared, it also takes a pointer to A to become the implicitly available this. It also has a different type than normal function pointers: bool (A::)(int, int) which decays into bool (A::*)(int, int) when being passed by value.

You could std::bind() your function to a suitable object, however:

std::sort(vec.begin(), vec.end(),
          std::bind(&A::cmp, this, std::placeholders::_1, std::placeholders::_2));
Sign up to request clarification or add additional context in comments.

4 Comments

I was going to suggest him to make it a static function... your advice is a lot more complete.
@Jekyll: Suggesting a static member was my first idea, too, but the code actually uses A::text in the A::cmp() function, i.e., the object is actually needed. That is, making the function static wouldn't solve the problem!
since the bind function was only introduced in c++11 I wonder how could you deal with it before the new standard?(I don't really need it, just curious)
@SAD: well, you could use Boost's bind() or write a custom function object class, e.g.: struct cmp { std::string const* name; cmp(std::string const* name): name(name) {} bool operator()(int a, int a) const { return std::lexicographical_compare(...); } };
0

The answer by @DietmarKühl explains perfectly, why your code does not compile. But since C++11, you can also use a lambda expression instead of defining a comparison function or making it static:

#include <vector>
#include <algorithm>

class A{
private:
    std::string text;
    std::vector<int> array;

    void build(const std::string &str, std::vector<int> &vec) {

        // Some vector values actions.

        std::sort(vec.begin(), vec.end(), [this](int a, int b) {
            return std::lexicographical_compare(text.begin() + a, text.end(),
                                                text.begin() + b, text.end());
        });
    }
};

I order to be able to access the class member text in the lambda expression, I captured the this pointer. However, if you want an alternative to capturing this, please take a look at this answer.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.