This SOの投稿は、実際には言語が引数のためだけに一時変数を受け入れることをサポートしているようです。なぜunique_ptrは一時的なものだけを受け入れることにしたのですか?
なぜこのように、受け入れられたエイリアスポインタに設計されたunique_ptrを、次に示します。これは助けにはならないので
auto uptr = std::unique_ptr<Widget>(new Widget{});
This SOの投稿は、実際には言語が引数のためだけに一時変数を受け入れることをサポートしているようです。なぜunique_ptrは一時的なものだけを受け入れることにしたのですか?
なぜこのように、受け入れられたエイリアスポインタに設計されたunique_ptrを、次に示します。これは助けにはならないので
auto uptr = std::unique_ptr<Widget>(new Widget{});
:
auto ptr = new Widget{};
auto uptr = std::unique_ptr<Widget>(ptr);
が理由だけに制限していません。
ポインタは、指定されたdeleterの適切な割り当て関数によって作成されている必要があります。これは一時的なものとは異なります。
new
式、関数呼び出し、および&
演算子で作成されたポインタを値カテゴリで区別することはできません。これらはすべて右辺値です。
"ポインタは' new'式を使って作成する必要があります。 - いいえ、そうではありません。デフォルトのDeleterはこれを必要としますが、他のDeleterも使用できます。 – hvd
@hvd OPで言及されているシナリオでは正しいです。 – milleniumbug
公正なポイント。しかし、 'unique_ptr'コンストラクタはOPによって記述されたシナリオに限定されないので、そのシナリオにのみ適用される理論的根拠には多少の欠陥があります。 – hvd
私が知る限りでは、正当な理由はありません。私は、これがライブラリからのC++言語の不完全な展開だと思います。
私はまだnew
からや工場のいずれかから、std::unique_ptr
受け入れることだけr値の参照のコンストラクタをしていないために十分な理由が見つからない同じ質問Why is raw pointer to shared_ptr construction allowed in all cases?
を尋ねました。ここで私はそれを答えにして、私が同意しない他の答えの同じレベルでそれを置くコメントではない。
実際に既存のポインタを受け入れる必要がある場合は、常にキャストすることができます。つまり、std::move
です。それは規範ではないので、言い訳ではありません。
ええと、なぜこの返信が投票されたのですか? – winterlight
代わりに 'std :: make_unique()'に制限するのはなぜですか? –
user975989
最初のシナリオは実際にはかなり有効ですが、2つの行の間にコードが追加されると簡単に例外が発生する可能性があります。第1のポインタはオブザーバポインタと呼ばれ、「uptr」は「所有ポインタ」と呼ばれる。同じリソースへの複数のオブザーバーポインターを持つことに何も問題はありません。また、 'std :: unique_ptr'は、既存のAPIを破壊することなく既存のコードベースで使用できるように、既存の"未処理の所有ポインタ "からの所有権を受け入れるべきです。 – KABoissonneault
@KABoissonneaultの場合、 'std :: unique_ptr up(std :: move(ptr));'を使うと、潜在的に危険なことをしていることを示すフラグを立てることができます。私の答えを見てください。 –
alfC