为什么auto_ptr不支持op - >*()

Ral*_*lly 17 c++ operator-overloading pointer-to-member

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
Run Code Online (Sandbox Code Playgroud)

当您尝试通过指向成员的指针调用成员函数时,存在差异,因为auto_ptr显然不实现op - >*():

void (MyClass::*memfun)() = &MyClass::foo;

(p->*memfun)();         // OK
(ap->*memfun)();        // Error op->*() missing
(ap.get()->*memfun)();  // OK
Run Code Online (Sandbox Code Playgroud)

为什么auto_ptr中不支持op - >*()以及如何实现它(我已经实验了一段时间,但最终放弃了).

Geo*_*che 8

正如路德指出其实施的重要性 - 但这是可能的.

你必须

  1. 使用模板,以便operator->*可以推导出参数的类型
  2. 使用重载来处理可能的限定符和多个函数arities
  3. 对于成员函数指针,返回一个callabe对象:
    • 绑定到智能指针指向的实例
    • 实现一个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);
}
Run Code Online (Sandbox Code Playgroud)

但最后,为什么我们可以在第一时间使用绑定成员指针的仿函数.

虽然我不能确定它,但如果你结合了这些知识

  • 实施是不平凡的
  • 有一个简单的替代方案也可以((*p).*m)

......它可能通常没有实施,因为这项功能所带来的工作所需的工作比例很差.


Nor*_*ame 4

实现 ->* 需要解决完美的转发问题:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm

operator->* 必须返回一个可调用对象,其参数列表与指向成员对象的指针相同,正确处理常量、易失性和引用类型。然后它必须使用特殊的魔力来处理默认参数。这是困难的、容易出错、无法解决的,并且会消耗太多的编译时间,而且由于指向成员的指针是 C++ 中相对不太受欢迎的功能,因此它们通常被排除在智能指针实现之外。