pointer to member function

▼魔方 西西 提交于 2019-12-01 20:24:20

Here is the syntax for the way you want:

vector<int> Table::filter(string s, string (Row::*get)() const)
{                                  //^^^^^^^^^^^^^^^^^^^^^^^^^^^ member pointer
  ...
  if(((*it).*get)() == s) {  // call using the (*it). and not it->
  ... 
}

Call it as:

vector<int> vx = t.filter("x1", &Row::getX);
vector<int> vy = t.filter("y2", &Row::getY);

A member function requires a pointer to the object instance. That is, think of getX as string Row::getX(const Table *this). You need to bind the member function with an instance placeholder.

E.g. using tr1,

vector<int> vx = t.filter("x1", std::bind(&Row::getX, std::placeholders::_1));

The binding creates a functor that takes in a Row object, assuming that your filter function is correctly defined. You should show code for filter. I presume it should be:

template <class function>
vector<int> Table::filter(const string &s, function f)
{
    vector<int> result;
    for (vector<Row>::const_iterator it = d_table.begin(), tEnd = d_table.end();
        it != tEnd; ++it)
    {
        if (s == f(*it)) result.push_back(it->getVal());
    }
    return result;
}

Here is how to do it by using pointer to member functions:

// helper to avoid type nightmare;
typedef string (Row::* GetterP)() const;

class Table 
{ 
public: 
    void add(string x, string y, int val); 

    // Define a templated function that can be called with GetX or GetY
    template <GetterP getter>
    vector<int> filter(string s)
    {
         int i = (d_table[i].*getter)(); // how to use getter in filter
    }

private:
    vector<Row> d_table;  
};

// Usage:
Table t;
t.filter<&Row::GetX>("");

If you want to use explicit PMF ( or at least see how they are used):

Declare the PMF type:

class Row 
{
    public:
    typedef string (Row::*getFilter)() const;
     // etc.
};

class Table
{
    public:
    // Call it like this:

    vector<int> pmf_filterX(string s)
    {
        return filter(s, &Row::getX);
    }
    private:
    // Use it like this:
    vector<int> filter(string s, Row::getFilter f)
    {
        vector<int> result;
        vector<Row>::iterator it;
        for(it = d_table.begin(); it != d_table.end(); ++it)
            {
            const Row& row = *it;

            if ((row.*f)() == s) 
                {
                int val = it->getVal();
                result.push_back(val);
                }
            }
        return result;
    }
};

Modify your code here:

public:
    void add(string x, string y, int val);
    vector<int> filter(string s, string (Row::*)() const);
private:
    ...

Here:

vector<int> Table::filter(string s, string (Row::*f)() const)
{   
    vector<int> result;
    vector<Row>::iterator it;
    for(it = d_table.begin(); it != d_table.end(); ++it) {
        if((*it.*f)() == s) {
            int val = it->getVal();
            result.push_back(val); 
        }
    }
    return result;
}

And here:

int main()
{
    ...
    vector<int> vx = t.filter("x1", &Row::getX);
    vector<int> vy = t.filter("y2", &Row::getY);

    ...
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!