5

std::shared_ptrそのクラスのコピーを作成するときに心配する必要がないように、クラス内のいくつかの生のポインターをに置き換えたかったのです。ただし、生のポインターは動的配列を指します。動的配列でshared_ptrを使用するには、カスタム削除機能を指定します。g。default_delete<T[]>

しかし、構築中であっても、そのフィールドに新しい値を割り当てようとするとすぐに、大きなエラーリストが表示されます。

最小限のコードサンプルを次に示します。

#include <memory>
#include <cstddef>

using namespace std;

template<typename T> shared_ptr<T[]> make_shared_array(size_t size)
{
  return shared_ptr<T[]>(new T[size], default_delete<T[]>());
}

struct Foo
{
  shared_ptr<char[]> field;
};

int main()
{
  Foo a;
  // This line produces the error.
  a.field = make_shared_array<char>(256);

  return 0;
}

NB:vectorはい、動的配列の代わりにできる/すべきであることを私は知っています。しかし、それらのパフォーマンスは同じではありません。私はいくつかの重い画像処理を行い、配列はピクセルを保持します。VGA解像度未満では、処理時間が8秒から11秒に増加しました。それはかなりたくさんです。


更新:もちろん、ここでエラーを提供できます。問題の説明を乱雑にする必要があるかどうかはわかりませんでした。しかし、ここにあります:

C:\ Program Files(x86)\ Microsoft Visual Studio 11.0 \ VC \ INCLUDE \ memory(754):エラーC2664:'std :: _ Ptr_base <_Ty> :: _ Reset0':パラメーター1を'char 'から'charに変換できません()[]'
with
[
_Ty =char[]
]
ポイントされたタイプは無関係です。変換には、reinterpret_cast、Cスタイルのキャスト、または関数スタイルのキャストが必要です
。C:\ Program Files(x86)\ Microsoft Visual Studio 11.0 \ VC \ INCLUDE \ memory(723):関数テンプレートのインスタンス化への参照を参照してください'void std :: shared_ptr <_Ty > :: _ Resetp0 <_Ux>(_ Ux *、std :: _ Ref_count_base *)'は
[
_Ty
= char []、


C:\ Program Files(x86)\ Microsoft Visual Studio 11.0 \ VC \ INCLUDE \ memory(723):関数テンプレートのインスタンス化への参照を参照'void std :: shared_ptr <_Ty> :: _ Resetp0 <_Ux>(_ Ux *、std: :_Ref_count_base *)' [ _Ty = char []、 _Ux = char ]
でコンパイル C:\ Program Files(x86)\ Microsoft Visual Studio 11.0 \ VC \ INCLUDE \ memory(494):関数テンプレートのインスタンス化への参照を参照' void std :: shared_ptr <_Ty> :: _ Resetp <_Ux、_Dx>(_ Ux *、_ Dx)'は [ _Ty = char []、 _Ux = char、 _Dx = std::default_delete ]でコンパイルされます











C:\ Program Files(x86)\ Microsoft Visual Studio 11.0 \ VC \ INCLUDE \ memory(494):関数テンプレートのインスタンス化への参照を参照'void std :: shared_ptr <_Ty> :: _ Resetp <_Ux、_Dx>(_ Ux *、 _Dx)'は
[
_Ty
= char []、
_ Ux = char、
_Dx = std :: default_delete
] problem.cpp
(9)でコンパイルされます:関数テンプレートのインスタンス化への参照を参照してください' std :: shared_ptr <_Ty> :: shared_ptr>( _Ux *、_ Dx)'は
[
_Ty
= char []、
T = char、
_Ux = char、
_Dx = std::default_delete
]でコンパイルされます
problem.cpp(9):[_ Ty = char []、
T = char、 _Ux = char、 _Dx = std :: default_delete ] problem.cpp(21): [ _Ty =char[] ] でコンパイル さ れている関数テンプレートのインスタンス化'std:: shared_ptr <_Ty> make_shared_array(size_t)'への参照を参照してください。










4

4 に答える 4

8

あなたが提案する解決策は可能ですが、配列のサイズが失われます:

#include <memory>
#include <cstddef>

using namespace std;

template<typename T> shared_ptr<T> make_shared_array(size_t size)
{
   return shared_ptr<T>(new T[size], default_delete<T[]>());
}

struct Foo
{
  shared_ptr<char> field;
};

int main()  
{
  Foo a;
  a.field = make_shared_array<char>(256);

 return 0;
}

ここで行ったことは、配列をポインターに減衰させることです。デリータが配列デリータである限り、正しく動作するはずです。

このサイズの損失を防ぐために、提案されているように boost::shared_array を使用できない場合は、この情報を独自の shared_array クラスにカプセル化することをお勧めします。

于 2013-02-19T12:38:34.440 に答える
4

を使用すべきではないと主張する場合std::vector、Boost にはboost::shared_array、動的に割り当てられたオブジェクトの配列を管理するためのスマート ポインターとして機能する があります。

shared_ptr配列を処理するようには設計されていません。が利用可能であるため、配列sshared_arrayで使用しようとするのはなぜですか?shared_ptr

于 2013-02-19T12:26:45.947 に答える
3

std::unique_ptrは配列タイプに特化しているため、配列タイプで使用でき、まだ。T[]を格納しているだけであることがわかりT*ます。std::shared_ptrはこのように特殊化されていないためshared_ptr<T[]>、配列へのポインタを格納しようとしますT(*)[]。これは、C++の生の配列に関する規則ではうまく機能しません。言うまでもなく、サイズが不明な配列は不完全な型であり、shared_ptr最終的には完全な型が必要になります。

std::vectorあなたはそれがより良い解決策であるべきだと知っていると言いますが、うまく機能しません。それはうまく機能するはずであり、なぜそうでないのかを理解したほうがよいでしょう。

于 2013-02-20T19:42:49.300 に答える
3

デリータを指定した場合T[]は、テンプレート引数で使用しません。に変更T[]するだけTです:

template <typename T> shared_ptr<T> make_shared_array(size_t size)
{
  return shared_ptr<T>(new T[size], default_delete<T[]>());
}

struct Foo
{
  shared_ptr<char> field;
};
于 2013-02-19T13:09:04.693 に答える