2013-04-15 54 views
1

采取以下为例如: (注意,示例不起作用,但应该足以说明什么,我试图做)使用函数指针不知道的情况下提前

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 
    } 
}; 

编辑:

的问题是操作的顺序;呼叫周围的编译器所需的括号这样:

(it->*func)() 
+0

在添加更多使用它的代码之前,您应该修复'Polygon :: get'中的编译错误。 –

+1

相关:http://stackoverflow.com/questions/6586205/what-are-the-pointer-to-member-and-operators-in-c/6586248#6586248 –

回答

2

它看起来像你想使用一个“指针成员函数”,它使用的语法如下:

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 
    } 
}; 

免责声明:未经测试。

此外,你可能想看看库C++11;对这样的事情非常好。

我这是怎么可能亲自接近的情况:

#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)); 
    } 
}; 

免责声明:编译,但未经测试。

+0

试过。编译错误。虽然这导致我面临真正的问题:操作顺序。问题更新。 – steveo225

1

在您的程序中更改了很多东西。指向成员语法的指针与指向函数语法的指针不完全相同。

我已经使用typedef和从C++的宏来简化此

​​

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;); 
    } 
}; 

解释评价的变化。

+0

这是正确的,虽然可以通过添加括号来简化它,正如我在编辑问题时所指出的那样。谢谢 – steveo225

+0

@ steveo225 - 好的,宏和typedef可以帮助您避免在原始问题中出现错误。 – user93353

相关问题