看起来operator->*()
运算符没有超载为std::unique_ptr<T>
。原因为什么这个算子没有被定义是不完全清楚的,尽管我认为在智能指针被提出的时候,处理合适超载的必要机制并没有到位。
问题是operator->*()
需要处理返回绑定结果。对于一个简单的成员函数来说,这是相当简单的,但对于函数来说,它并非完全无关紧要。这里是unique_ptr<T>
类模板的简约变化,这只是显示的实施将看起来像:
template <typename T>
struct unique_ptr
{
T* p_;
unique_ptr(T* p): p_(p) {}
T* operator->() { return this->p_; }
template <typename R>
R& operator->*(R T::*mem) { return this->p_->*mem; }
template <typename R>
auto operator->*(R (T::*mem)()) ->decltype(std::bind(mem, this->p_))
{
return std::bind(mem, this->p_);
}
};
该版本仅与指针的成员变量和指针成员函数不带参数的对应。我需要对operator->*()
运算符的版本进行一些修改,以获得任意数量的参数。成员变量指针的版本很简单:它只需要返回一个引用对应的成员。成员函数的版本需要创建一个第一个(隐式)参数绑定到正确对象的可调用对象。
处理任意数量的参数需要使用可变参数进行一些处理。的unique_ptr<T>
的定义还面临着采取论证会是这个样子的成员函数指针:
template <typename T>
struct unique_ptr
{
private:
T* p_;
template <typename R, typename... A, int... I>
auto bind_members(R (T::*mem)(A...), indices<I...>)
-> decltype(std::bind(mem, this->p_, placeholder<I + 1>()...))
{
return std::bind(mem, this->p_, placeholder<I + 1>()...);
}
public:
unique_ptr(T* p): p_(p) {}
T* operator->() const { return this->p_; }
template <typename R>
R& operator->*(R T::*mem) { return this->p_->*mem; }
template <typename R>
auto operator->*(R (T::*mem)()) ->decltype(std::bind(mem, this->p_))
{
return std::bind(mem, this->p_);
}
template <typename R, typename... A>
auto operator->*(R (T::*mem)(A...))
-> decltype(this->bind_members(mem,
typename indices<sizeof...(A) - 1>::type())) {
return this->bind_members(mem,
typename indices<sizeof...(A) - 1>::type());
}
};
主要的窍门在于创建参数适合的占位符的序列。相应的帮助类是这样定义的:
template <int... Indices> struct indices;
template <> struct indices<-1> { typedef indices<> type; };
template <int... Indices>
struct indices<0, Indices...>
{
typedef indices<0, Indices...> type;
};
template <int Index, int... Indices>
struct indices<Index, Indices...>
{
typedef typename indices<Index - 1, Index, Indices...>::type type;
};
template <int I>
struct placeholder
: std::integral_constant<int, I>
{
};
namespace std
{
template <int I>
struct is_placeholder<placeholder<I>>
: std::integral_constant<bool, true>
{
};
}
什么是错误?另外,不需要整个来源。 – sashoalm
VC2010给出错误C2296,非法,左操作符包括std :: unique_ptr <_Ty> – user1899020
你可以编辑问题并将其添加到它吗? – sashoalm