我曾经使用转换构造函数编写类似指针的结构(如智能指针,迭代器等),它允许单向非const转换为const。此样式可防止const /非const版本的代码重复。 e.g。
template<class T>
struct ptr_like
{
using self_type = ptr_like<T>;
using nonconst_self = ptr_like<remove_const<T>>;
ptr_like() : ptr_(){}
//a friendship may be needed to access private member
ptr_like(nonconst_self const& rhs) : ptr_(rhs.ptr_){//implementation} 1)
//ptr_like(ptr_like const& rhs) = default; 2)
T* ptr_;//exposition only
};
ptr_like<int> x1,x2 = x1;//converting constructor
ptr_like<int const> x3,x4 = x3;//default constructor
//ptr_like<int> x5 = x3; //error as intended
ptr_like<int const> x6 = x1;//converting constructor, allowed conversion.
但是在c ++ 11 is_trivially_copy_constructible
中ptr_like<T>
为false,而ptr_like<T const>
为true,实际上使用ptr_like<T>
作为类的成员变量会删除默认值移动构造函数(因为它具有非平凡的复制构造函数,并且没有可用的移动构造函数),而使用ptr_like<T const>
作为类的成员是完美的,因为它具有普通的复制构造函数。
e.g。
struct holder
{
ptr_like<int> p;//(3
holder(holder const&) = delete;
holder(holder&&) = default;
};
is_move_constructible<holder>() == false
std::vector<holder> v;
holder h;
v.push_back(std::move(h)); //this fails as no move constructor possible.
为ptr_like
提供默认的复制构造函数(如2)也没用,因为它已经实现了ptr_like<T>
这种效果可以在许多提升类中看到(例如boost::circular_buffer<T>::iterator
),其中将它们存储在类中会禁用该类的移动构造函数。而且,当未删除复制构造函数时,它会默默地复制。
所以,问题是,在c ++ 11中用重复代码编写像类这样的类的指针的最佳方法是什么? (作为一个辅助问题,我正在寻找当成员变量具有非平凡的复制构造函数时为类禁用移动构造函数的原因)