2011-03-22 30 views
2

有没有办法将->*重载用于类似智能指针的对象?以下是我想要做的。为了简单起见,我没有使用模板(一旦我为单个固定类别工作,我会做到这一点)。我可以使用它指向数据成员,但我似乎无法为成员函数的指针指出正确的方向。目前,我愿意解决只适用于成员函数的重载(而不适用于数据成员)。我甚至愿意解决一个重载,只接受指向具有单个固定原型的成员函数的指针(如void func())。如何在C++中重载operator - > *

struct MyObject 
{ 
    void MyMethod() {} 
}; 

struct MySmartPtr { 
    MyObject *p; 

    // What should the prototype and function body be? 
    // ??? operator->*(????) { ???? } 
}; 

void MyFunc() 
{ 
    MyObject obj; 
    MySmartPtr obj_ptr; 
    obj_ptr.p = &obj; 
    void (MyObject::* member_func_ptr)() = &MyObject::MyMethod; 

    // Now call obj.MyMethod() through the "smart pointer" 
    (obj_ptr->*member_func_ptr)(); 
} 

请不要给我解决方法(例如,过载*(*obj_ptr.*member_func_ptr)())。我想要->*按照代码片段中的说明工作。

+1

什么是运算符 - > *? – 2011-03-22 09:51:44

+0

@Tobias:我在答案中链接的文章也解释了这一点。 – sbi 2011-03-22 09:52:23

回答

12

看看Scott Meyers的this article。这是相当古老,但唯一的资源讨论,我知道超载->*

请注意,标准库的迭代器和智能指针类型不会超载->*。我不知道原因,但我怀疑这是因为该操作员很少使用过,实施起来很麻烦,而且很容易解决这个问题。无论如何,由于标准库不支持它,你的用户也不会期望它能够工作。

+0

+1链接到非常好的文章! – Xeo 2011-03-22 10:22:55

+0

有趣的文章,但相当令人失望,因为它似乎必须返回一个仿函数。我不喜欢它。 – Ari 2011-03-22 11:45:57

1

http://codepad.org/yl3Ghwab

#include <stdio.h> 

struct OBJ { 
    typedef void (OBJ::*Met)(void); 
    void met(void) { 
    printf("Method call!\n"); 
    } 
}; 

struct POBJ { 
    OBJ* p; 
    typedef void (*fun)(void); 
    static void nop(void) {} 
    fun operator->*(OBJ::Met m) { 
    printf("operator ->* !\n"); 
// return fun(p->*m); // works in gcc 
    (p->*m)(); 
    return nop; 
    } 
}; 

int main(void) { 
    OBJ obj; 
    OBJ* pobj = &obj; 
    POBJ p; p.p = &obj; 
    OBJ::Met met = &OBJ::met; 
    (pobj->*met)(); 
    (p->*met)(); 
} 

原型

+0

嗯,严格地说,这确实满足了我提出的要求,但让操作符函数执行实际的调用,并返回NOP不是我想要的。我怀疑这个解决方案不会延伸到任意原型。 'return fun(p - > * m)'看起来像我之后的东西,但并不真正起作用,因为它返回一个指向独立函数的指针(一个不带'this'指针的指针,所以无法访问班级的数据成员)。如果我将数据成员添加到'OBJ'并让'met'尝试访问它们,我会遇到分段错误。 – Ari 2011-03-22 11:20:04

0

http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B我给它用C++拍0X:可变参数模板,绑定和功能。我想这应该有可能将它移植到提升:

#include <iostream>                
#include <functional>               

struct S 
{  
    void f() 
    { 
    std::cout << __PRETTY_FUNCTION__ << std::endl; 
    } 
}; 

template<class C> 
struct PMFSmartPtr 
{ 
    C *p; 
    template<typename C1, typename R, typename... P> 
    std::function<R(P...)> operator->*(R (C1::*pmf)(P...)) 
    { 
    std::cout << __PRETTY_FUNCTION__ << std::endl; 
    return(std::function<R(P...)>(std::bind(pmf, p))); 
    } 
}; 

int main() 
{ 
    PMFSmartPtr<S> x; 
    void (S::*pmf)() = &S::f; 
    (x->*pmf)(); 
    return(0); 
} 

试戴G ++ 4.4.4和工程功能不采取任何参数,为1个参数的成员函数编译失败,但我不知道这是不是我的故障或编译器或libstdC++问题...