# unique_ptr のconstとは? [unique_ptr](https://cpprefjp.github.io/reference/memory/unique_ptr.html) にconst修飾子がついているケースがChromiumでも散見される。 ```cpp= const std::unique_ptr<viz::CompositorRenderPass>& render_pass = frame.render_pass_list.back(); ``` constがつくとどういう挙動になるのかを確認する。 ## そもそもconstとは constは変数前につけることでその変数の値を不変にする修飾子。 例えば`const int val = 0`と変数`val`を宣言すると違う値を再代入することはできない。 `val = 1`とかいたらコンパイルエラーになる。 constはポインタにつけると挙動がややこしくなる。 ポインタ変数は、指すアドレスそのものを変更できるかと、指す先の値を変更できるかの2タイプ存在する。 それはconstをつける位置によって変わる。 ```cpp= // 値の場合const intとint constは同じ const int val1 = 0; // val1 = 1; <- コンパイルエラー int const val1 = 0; // val2 = 1; <- コンパイルエラー // ポインタの場合constとint*のどちらを先に書くかで変わる int val = 0; const int* ptr1 = &val; ptr1 = nullptr; // <- OK // *ptr1 = 1; <- コンパイルエラー int* const ptr2 = &val; // ptr2 = nullptr; <- コンパイルエラー *ptr2 = 1; // <- OK // どちらもつけることもできる。その場合どちらも制約がつく const int* const ptr3 = &val; // ptr3 = nullptr; <- コンパイルエラー // *ptr3 = 1; <- コンパイルエラー ``` ## std::unique_ptrの場合 ではstd::unique_ptrとconstの関係を見る。 まず先頭にconstをつけてみる。 ```cpp= const std::unique_ptr<int> uptr1 = std::make_unique<int>(0); // uptr1 = nullptr; <- コンパイルエラー *uptr1 = 1; // <- OK ``` 生ポインタにおける`int* const ptr2`と同じ挙動をした。 では`const int*`にあたる書き方はどうすればいいかというと以下。 ```cpp= std::unique_ptr<const int> uptr2 = std::make_unique<const int>(0); uptr2 = nullptr; // OK // *uptr2 = 1; <- コンパイルエラー ``` 格納する値をconstにすればよい。 生ポインタと同様に、どちらも不変にすることもできる。 ```cpp= const std::unique_ptr<const int> uptr3 = std:make_unique<const int>(0); // uptr3 = nullptr; // *uptr3 = 1; ``` const auto みたいに書けば良かった… ## Note: std::unique_ptrのconst参照渡し? 関数にconst参照渡しをする場合、その関数内で引数の値を書き換えられないことを期待している。 std::unique_ptrの先頭にconstをつけても格納されている値は書き換えられてしまうので要注意。 値を取り出してconst参照で渡すのが一番よさそう? ```cpp= void Func(const A& a); auto a = std::make_unique<A>(); Func(*a); ```