2017-04-09 8 views
10

:C++ 11とC++ 14ではarrayのunique_ptrからのshared_ptrの作成がなぜもはや許可されていないのですか? <a href="http://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr" rel="noreferrer">cppreference</a>から

std::unique_ptr<T[]> からstd::shared_ptr<T>を構築するために有効である:shared_ptrがデリータを取得するため

std::unique_ptr<int[]> arr(new int[1]); 
std::shared_ptr<int> ptr(std::move(arr)); 

std::default_delete<T[]>オブジェクト)をunique_ptrから削除すると、配列は が正しく割り当て解除されます。

これはC++では許可されていません17。代わりに、配列形式 std::shared_ptr<T[]>を使用する必要があります。

なぜC++では許可されていないのですか17?変化したこと?

+0

いくつかの測定値あなたがしたい場合:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0414r2.html – Holt

答えて

13

p0497r0:実装経験に基づいて

unique_ptrを

からshared_ptrの構築のための不正な制約[...]

私は正しいフォームがあると信じて:

備考:このコンストラクタは、 Y*T*と互換性があり、unique_ptr<Y, D>::pointerelement_type*に変換されていない場合を除いて、オーバーロードの解像度を予期します。

チェックがshared_ptr<T>unique_ptr<T[]>への望ましくない変換を防止し、「コンバーチブルに」チェックがunique_ptr<Y, D>::get()の結果はshared_ptrに格納され、shared_ptr<T>::get()によって戻すことができるようになります。「との互換性」

つまり、単に他の変更の副作用ではなく、無効にするべきであるという理由だけで意図的に無効にしました。

私には意味があります。 shared_ptr<T>は、1つのTオブジェクトだけを指していると他のプログラマによって読み取られる可能性があります。複数のTオブジェクトが必要なときにプログラマにshared_ptr<T[]>を使用させると、より読みやすいコードになります。

注:この正しい形式は標準ではありません。しかし、その根拠は、標準的なものについてのコメントです。

+0

私はそれが '' unique_ptrをすべきでないということが合理的であると考えます'shared_ptr 'に変換されます。しかし、後方互換性を破る価値があるのでしょうか? – ikh

+3

@ikh元々、* no *チェックは全くありませんでした。これは、ジェネリックコードがSFINAEを使って 'std :: unique_ptr 'を 'std :: shared_ptr 'に暗黙的に変換することをナンセンス。 ( 'static_assert(std :: is_convertible 、std :: shared_ptr >()、" ");'を渡す必要がありました。)これを修正するために文言が調整されていれば、それはすぐにそれを得る価値があると思います。 – hvd

+0

@ikhまた、特定の変換が必要な場合、共用ptrエイリアシングコンストラクタは回避策です。 'auto tmp = shared_ptr (std :: move(up))と似ています。自動sp = shared_ptr (tmp.get()、tmp); ' – Yakk

関連する問題

 関連する問題