I have a class as below
class A
{
public:
A(int key) : m_key(key) {}
int Key() const {return m_key;}
private:
int m_key;
};
I test using unique_ptr with member function pointer
int (A::*MemFun)() const;
MemFun = &A::Key;
( std::unique_ptr<A>(new A(10)) ->*MemFun ) (); // Error C2296
( std::unique_ptr<A>(new A(10)).get() ->*MemFun ) (); // okay
(*std::unique_ptr<A>(new A(10)) .*MemFun ) (); // okay
The first one gives a compilation error (VC2010 gives error C2296, illegal, left operator includes std::unique_ptr<_Ty>). Why? Thanks.
It seems the
operator->*()operator isn’t overloaded forstd::unique_ptr<T>. The reason why this operator isn’t defined isn’t entirely clear although I think that at the time when the smart pointers were proposed the necessary mechanics for dealing with the suitable overloads were not in place.The problem is that
operator->*()needs to deal with returning the bound result. For a simple member function this is reasonably simple but for functions it isn’t entirely trivial. Here is a minimalistic variation of theunique_ptr<T>class template which just shows the implementation would look like:This version merely copes with pointers to member variables and pointer to member functions with no arguments. I need to meditate a bit over a version of the
operator->*()operator for arbitrary number of arguments. The version for pointer to member variables is trivial: It just needs to return a reference the corresponding member. The version for member functions needs to create a callable object with the first (implicit) parameter being bound to the correct object.Dealing with an arbitrary number of arguments take a bit of playing with variadic arguments. A definition of
unique_ptr<T>also dealing with member functions pointers taking arguments could look something like this:The main trick consists in creating a sequence of suitable placeholders for the arguments. The corresponding helper classes are defined thus: