1

Take the following as a example: (Note, the example doesn't work, but it should be enough to illustrate what I am trying to do)

class Point {
    float x, y;
public:
    float getX() const { return x; }
    float getY() const { return y; }
};

class Polygon {
    std::vector<Point> points;

    std::vector<float> get(float (Point::*func)()const) {
        std::vector<float> ret;
        for(std::vector<Point>::iterator it = points.begin(); it != points.end(); it++) {
            // call the passed function on the actual instance
            ret.push_back(it->*func());
        }
        return ret;
    }

public:
    std::vector<float> getAllX() const {
        return get(&Point::getX); // <- what to pass for getX
    }
    std::vector<float> getAllY() const {
        return get(&Point::getY); // <- what to pass for getY
    }
};

EDIT:

The problem was order of operations; the compiler required parenthesis around the call as such:

(it->*func)()
2

2 Answers 2

2

It looks like you want to use a "pointer to a member function", which uses the following syntax:

class Point {
    float x, y;
public:
    float getX() const { return x; }
    float getY() const { return y; }
};

class Polygon {
    std::vector<Point> points;

    std::vector<float> get(float (Point::*func)()) { // !!! NEW SYNTAX - POINTER TO MEMBER
        std::vector<float> ret;
        for(std::vector<Point>::iterator it = points.begin(); it != points.end(); it++) {
            // call the passed function on the actual instance
            ret.push_back((it->*func)()); // !!! ADDED PARENTHESES
        }
        return ret;
    }

public:
    std::vector<float> getAllX() const {
        return get(&Point::getX); // !!! POINTER TO MEMBER
    }
    std::vector<float> getAllY() const {
        return get(&Point::getY); // !!! POINTER TO MEMBER
    }
};

Disclaimer: Untested.

Also, you might want to look into the <functional> library in C++11; it's very nice for things like this.

This is how I might personally approach the situation:

#include <functional>
#include <vector>
#include <algorithm>

class Point {
    float x, y;
public:
    float getX() const { return x; }
    float getY() const { return y; }
};

class Polygon {
    std::vector<Point> points;

    std::vector<float> get(std::function<float(const Point&)> func) const {
        std::vector<float> ret(points.size());
        std::transform(points.begin(), points.end(), ret.begin(), func);
        return ret;
    }

public:
    std::vector<float> getAllX() const {
        return get(std::mem_fn(&Point::getX));
    }

    std::vector<float> getAllY() const {
        return get(std::mem_fn(&Point::getY));
    }
};

Disclaimer: Compiles, but untested.

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

1 Comment

Tried that. Compile errors. Although this lead me to the real problem: order of operations. Updated in question.
1

Changed lot of stuff in your program. Pointer to member syntax is not exactly the same as pointer to function syntax.

I have used a typedef and a macro from the C++ to simplify this

http://www.parashift.com/c++-faq/typedef-for-ptr-to-memfn.html

http://www.parashift.com/c++-faq/macro-for-ptr-to-memfn.html

class Point {
    float x, y;
public:
    float getX() const { return x; }
    float getY() const { return y; }
};

// This typedef makes is easier to declare a pointer to a member method
typedef float (Point::*PointPtr)() const;
// This macro makes it easier to call through a member function pointer.
#define CALL_MEMBER_FN(object,ptrToMember)  ((object).*(ptrToMember))

class Polygon {
    std::vector<Point> points;

    // Made this a const function. And changed the parameter type.
    std::vector<float> get(PointPtr func) const {
        std::vector<float> ret;

        // Made this a const iterator
        for(std::vector<Point>::const_iterator it = points.begin(); it != points.end(); it++) {
            // Changed the call to use the macro
            ret.push_back(CALL_MEMBER_FN((*it), func)());
        }
        return ret;
    }

public:
    std::vector<float> getAllX() const {
        return get(&Point::getX); 
    }
    std::vector<float> getAllY() const {
        return get(&Point::getY;);
    }
};

Explained the changes in the comments.

2 Comments

That is correct, although it can be done more concisely by just adding parenthesis as I noted in the edit to the question. Thanks
@steveo225 - well, the macro and the typedef help you avoid making the error you made in the original question.

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.