2

以前は、非 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_constructiblefalse であるのに対しptr_like<T>、 に対して true であるため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 で重複コードを使用してポインターのようなクラスを作成する最良の方法は何ですか? (補助的な質問として、メンバー変数に自明でないコピー コンストラクターがある場合にクラスのムーブ コンストラクターが無効になる理由を探しています)

4

0 に答える 0