我曾经使用转换构造函数编写类似结构的指针(如智能指针、迭代器等),它允许一种非 const 到 const 转换的方式。这种风格可以防止 const/non-const 版本的代码重复。例如
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
对于 是 false ptr_like<T>
,而对于ptr_like<T const>
,实际上使用ptr_like<T>
作为类的成员变量会删除默认的移动构造函数(因为它具有非平凡的复制构造函数,并且没有可用的移动构造函数),而它是完美的用作ptr_like<T const>
类的成员,因为它具有简单的复制构造函数。例如
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.
为(如 2)提供一个默认的复制构造函数ptr_like
也是无用的,因为它已经实现了一个复制构造函数ptr_like<T>
这种效果可以在许多提升类(例如boost::circular_buffer<T>::iterator
)中看到,其中将它们存储在一个类中会禁用该类的移动构造函数。而且,当复制构造函数没有被删除时,它会默默地复制。
那么,问题是,在 c++11 中编写带有重复代码的类指针的最佳方法是什么?(作为一个辅助问题,我正在寻找当成员变量具有非平凡的复制构造函数时为类禁用移动构造函数的原因)