2013-04-15 92 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

相關問題