在处理类成员函数指针时,我们可以使用以下语法在对象实例上调用函数:
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()
)时的行为
答案 0 :(得分:3)
编译器是否应该拒绝上面的箭头语法?因为通常(静态调用函数时),它调用operator - &gt;。不应该只是调用运算符 - &gt;?
编译器正确拒绝语法。否operator->*
不应调用operator->
(根据标准)。请注意,尽管语法可能看起来相似,但->*
本身就是一个运算符,而不是->
与其他*
事物的组合。
答案 1 :(得分:1)
您可以为智能指针重载operator->*
。请参阅Scott Meyers撰写的this文章。基本思想是返回一个从操作符返回后将被调用的函数对象。
这篇文章有点过时,你现在只能使用一个可变参数模板作为变量函数参数号。