在智能指针上调用成员函数指针

时间:2013-03-25 12:25:44

标签: c++ c++11 operator-overloading smart-pointers member-function-pointers

在处理类成员函数指针时,我们可以使用以下语法在对象实例上调用函数:

struct X {
    void foo();
};

X x;                // Instance
auto f = &X::foo;   // Member function pointer

(x.*f)();           // Call function f on x

当拥有实例的原始指针时,语法为:

X *xptr = new X();

(xptr->*f)();

这很好地遵循静态函数调用的类比:

x.foo();
x->foo();

但是,当我有一个类的智能指针时,这不起作用:

unique_ptr<X> xsptr(new X());

(xsptr->*f)();    // g++: error: no match for 'operator->*' in 'xsptr ->* f'

我首先应用解除引用运算符,然后使用.语法调用来解决此问题:

((*xsptr).*f)();

这有多难啊?

编译器是否应该拒绝上面的箭头语法?因为通常(静态调用函数时),它会调用operator ->->*不应该只是致电operator ->吗?

编译器错误部分回答了这个问题:错误读取,因为我们可以重载operator ->*来调用解除引用对象上的成员函数指针,unique_ptr不会。但这引入了更多问题。如果语言需要,为什么智能指针不能这样做呢?是否这样做是因为它引入了其他问题?为什么我们必须编写这个运算符而不是隐式调用->返回的对象上的成员函数指针? (因为这是写xsptr->foo())时的行为

2 个答案:

答案 0 :(得分:3)

  

编译器是否应该拒绝上面的箭头语法?因为通常(静态调用函数时),它调用operator - &gt;。不应该只是调用运算符 - &gt;?

编译器正确拒绝语法。否operator->*不应调用operator->(根据标准)。请注意,尽管语法可能看起来相似,但->*本身就是一个运算符,而不是->与其他* 事物的组合。

答案 1 :(得分:1)

您可以为智能指针重载operator->*。请参阅Scott Meyers撰写的this文章。基本思想是返回一个从操作符返回后将被调用的函数对象。

这篇文章有点过时,你现在只能使用一个可变参数模板作为变量函数参数号。