auto_ptr(shared_ptr)也尽量让它们尽可能透明;也就是说,理想情况下,您不应该区分是否使用auto_ptr或指向对象的实际指针。考虑:
class MyClass
{
public:
void foo() { }
};
MyClass* p = new MyClass;
auto_ptr<MyClass> ap(new MyClassp);
p->foo(); // No notational difference in using real
ap->foo(); // pointers and auto_ptrs
当您尝试通过指向成员的指针调用成员函数时,存在差异,因为auto_ptr显然没有实现op-&gt; *():
void (MyClass::*memfun)() = &MyClass::foo;
(p->*memfun)(); // OK
(ap->*memfun)(); // Error op->*() missing
(ap.get()->*memfun)(); // OK
为什么auto_ptr中不支持op-&gt; *()以及如何实现它(我已经实验了一段时间,但最终放弃了)。
答案 0 :(得分:8)
正如路德所指出的那样,实施它并非易事 - 但这是有可能的。
你必须
operator->*
的参数类型operator()
,其签名等同于成员函数忽略了momement的限定符,这里它基本上是如何看的(使用C ++ 0x来避免手动重复):
// pointer to data member:
template<class T, class D>
D& operator->*(std::auto_ptr<T>& p, D T::*mp) {
return (*p).*mp;
}
// pointer to member function:
template<class T, class R, class... Args> struct Callable {
typedef R (T::*MFP)(Args...);
MFP mfp;
T& instance;
Callable(T t, MFP mfp) : instance(t), mfp(mfp) {}
R operator()(Args... a) {
return (instance.*mfp)(a...);
}
};
template<class T, class R, class... Args>
Callable<T, R, Args...>
operator->*(std::auto_ptr<T>& p, R (T::*mfp)(Args...)) {
return Callable<T, R, Args...>(*p, mfp);
}
但最后,为什么我们可以在第一时间使用绑定成员指针的仿函数时烦恼呢。
虽然我不能确定它,但如果你结合了
的知识(*p).*m
)......由于此功能所带来的收益与所需工作的比例不佳,通常可能无法实施。
答案 1 :(得分:4)
实施 - &gt; *需要解决完美的转发问题:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm
operator-&gt; *必须返回一个可调用对象,该对象具有与指向成员对象相同的参数列表,正确处理const-,volatile和引用类型。然后它必须使用特殊的魔力来处理默认参数。这很难,容易出错,无法解决并且占用太多的编译时间,并且由于指向成员的指针是C ++的一个相对边缘流行的特性,因此它们通常被排除在智能指针实现之外。
答案 2 :(得分:0)
我可能错了,但我认为没有办法将operator->*
重载为指向成员函数的指针。这是因为p->*memfun
虽然作为将其视为可调用对象的表达式的一部分有效,但它本身不是有效表达式,并且没有类型。因此,运营商无法返回有效类型。
以下内容适用于指向成员的指针,但尝试将其用于指向成员指针的函数会产生错误,“无效使用非静态成员函数”,使用GCC和内部函数MSVC编译错误。
template <class CLASS, typename MEMBER>
MEMBER& operator->*(std::auto_ptr<CLASS>& p, MEMBER CLASS::*m)
{
return (*p).*m;
}
编辑:正如Georg的回答所指出的那样,你可以使用boost::bind
或者类似的方法为成员函数创建一组重载,直到固定的最大参数数量,但是仍然没有办法让所有人都重载运算符可能的成员职能。