将unique_ptr与成员函数指针一起使用时出错
Error in using unique_ptr with member function pointer
我有一个类如下
class A
{
public:
A(int key) : m_key(key) {}
int Key() const {return m_key;}
private:
int m_key;
};
我使用unique_ptr和成员函数指针进行测试
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
第一个给出编译错误(VC2010给出错误C2296,非法,左运算符包括std::unique_ptr<_Ty>(。为什么?谢谢
似乎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>
{
};
}
->*
语法是单个运算符("指向成员的指针"运算符之一(。此运算符可以重载,但std::unique_ptr
不执行此操作。
相关文章:
- 访问者访问变体并返回不同类型时出错
- 在Linux for Windows上编译C++代码时出错
- 尝试将指针与结构一起使用时出错
- 将运算符<<与隐式转换的非基本数据类型一起使用时出错
- 将外部C++库与 CMake 一起使用时出错
- 将 find_if() 与数组一起使用的代码段中出错
- 可能的 GCC 链接器错误会导致将弱符号和局部符号链接在一起时出错
- OpenGL 将来自 ttf 的渲染器文本与背景纹理组合在一起时出错
- 将 argv 与函数一起使用时出错
- 将calcOpticalFlowPyrLK与OpenCV 2.3.1一起使用时出错
- 在C++中将cout与变量一起使用时出错
- 将lower_bound与矢量<对<字符串、双精度一起使用时出错>>
- 将cvMinMaxLoc与IplImage一起使用时出错
- 将"using namespace boost::numeric::ublas;"与 stl 矢量一起使用时出错
- 将 boost::spirit::qi::p hrase_parse() 与 qi::grammar 一起使用时出错
- 在C++中一起编译源文件和头文件时出错
- "Numeric value out of range" 将 SQLFetch() 与 SQL_C_FLOAT 一起使用时出错
- 与矢量大小一起使用时,for 循环中出错
- 在Visual Studio 2010(utility.obj)中将QuickFix与VC++一起使用时出错
- 将unique_ptr与成员函数指针一起使用时出错