在处理类成员函数指针时,我们可以使用以下语法调用对象实例上的函数:
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()
)