2011-07-27 56 views
4

我有一个具有特殊数据结构的类Test。 甲Test类的成员是std::map其中键是一个std::string和映射的值是定义如下一个struct从结构中调用指针到成员函数指向的函数

地图
typedef struct { 
    void (Test::*f) (void) const; 
} pmf_t; 

初始化是OK。问题是当我试图调用指向的函数时。我编写了一个玩具的例子来重现这个问题。那就是:

#include <iostream> 
#include <map> 

using namespace std; 

class Test; 
typedef void (Test::*F) (void) const; 
typedef struct { 
    F f; 
} pmf_t; 


class Test 
{ 
public: 
    Test() { 
    pmf_t pmf = { 
     &Test::Func 
    }; 
    m["key"] = pmf; 
    } 
    void Func (void) const { 
    cout << "test" << endl; 
    } 
    void CallFunc (void) { 
    std::map<std::string, pmf_t>::iterator it = m.begin(); 
    ((*it).second.*f)(); // offending line 
    } 

    std::map<std::string, pmf_t> m; 
}; 


int main() 
{ 

    Test t; 
    t.CallFunc(); 

    return 0; 
} 

由于提前, JIR

回答

5

pmf_t类型的名称是f,所以第一个更改是删除*以获得second.f。这给你一个指向成员的值。若要使用指向成员,您需要一个实例。你拥有正确类型的只有一个是this,所以用->*运营商使用它:

(this->*it->second.f)(); 

您需要括号围绕整个事情,否则编译器认为你试图调用it->second.f()(其不允许),然后将结果应用到->*

+0

彻底的解释,谢谢。我从来没有想过在迭代器中加上'this'。 – Jir

+0

你没有把它加入迭代器;你将它加入到指向成员的表达式中。 (' - >'和'.'运算符的绑定比' - > *'更紧密;这里是一个完全括号的版本:'(this - > *((it-> second).f))()'。 –

1

我想你可能要在这一个检查出C++ FAQ。语法显然非常难以正确(他们实际上推荐使用宏)。

+0

我已经编辑使用'typedef'为例你建议。但是,我仍然无法弄清楚如何调用该函数。无论如何感谢您的意见! – Jir

+1

*创建*指向成员不是问题。 –

+0

@Rob,哎呀,我太早链接了一个条目。 OP实际上需要* next * FAQ,这表示使用宏调用该函数。我更新了链接。 –

1

试试这个:

(this->*((*it).second.f))(); 
3

出错行试图调用一个成员函数没有任何对象调用它。如果目的是叫它为this对象,我相信调用看起来应该像

( this->* ((*it).second.f))(); 

哪里this->*是语法解引用指针到成员当前对象。 ((*it).second.f)是从地图中检索的指针,()是实际调用该函数的调用操作符。

这可能是一个很好的练习,但在其他方面的使用有限。

1

它可能是太晚了这个问题,但在看似复杂的synatax可以分解为两个简单的线条,所以它看起来很清楚:

void CallFunc (void) 
{ 
    pmf_t t = m["key"]; //1>get the data from key 
    (this->*t.f)();  //2>standard procedure to call pointer to member function 
} 
+0

这有利于可读性。我想知道创建局部变量't'是否会对性能造成威胁。 – Jir

+0

我不认为这个额外的行是一般的性能拖动太多,但它增加了很多可读性。通过这种方式,项目可以得到更好的维护,因此,除非您告诉我此功能处于关键性能瓶颈,否则我会亲自支持此项目。 – Gob00st