14

クラス内のオブジェクトへのポインターのベクトルが必要です。std::unique_ptrクラスでオブジェクトが作成/所有/破棄されるため、デストラクタを作成しないようにするために使用したかったのですが、理解できないコンパイラエラーがあります。次のコードは、私の問題の短いサンプルとして機能します。

std::unique_ptr<int> createPtr(int value)
{
    std::unique_ptr<int> ptr(new int(value));
    return ptr;
};

int main()
{
    std::vector<std::unique_ptr<int>> vec;
    vec.push_back(createPtr(1));

    std::unique_ptr<int> ptr = createPtr(2);
    vec.push_back(ptr);//error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'
}

このエラーが発生する理由と、 の正しい使用法を教えてくださいstd::unique_ptr

4

3 に答える 3

15

を検討してくださいvec.push_back()const std::unique_ptr<int>&またはのいずれかを取る2つのオーバーロードがありますstd::unique_ptr<int>&&。最初のオーバーロードは使用できません。これはvector<>、タイプが割り当て可能または移動可能(C ++ 11追加)である必要があるためです。「割り当て可能性」はコピーを意味します。push_back(const T&)コンテナの最後にある新しいスペースに着信値をコピー(割り当て)しようとします。std::unique_ptr<>単一の所有者が所有するリソースを表します。それ(ポインタ)をコピーすることにより、複数の所有者が存在します。そのため、unique_ptrコピーすることはできません

とはいえ、T&&オーバーロードしか使用できません。

createPtr()を返しますstd::unique_ptr<int>が、これは一時的な結果(関数の戻り値)であるため、(暗黙的に)右辺値参照と見なされます。これが使用できる理由です。

ptrは、左辺値の参照であるだけです(名前付き右辺値は左辺値として扱われるstd::unique_ptr<int>ため、横に&&を付けてもかまいません) 。左辺値が暗黙的に右辺値に変換されることはありません(完全に安全ではありません)。しかし、基本的には、を使用することで、コンパイラに「わかりました。渡したオブジェクトを取得できます。引数がそのまま残ることはないと約束します」と伝えることができますstd::move()

于 2013-01-23T19:43:27.773 に答える
15

また:

vec.push_back(std::move(ptr));

または:

vec.emplace_back(createPtr(2));
于 2013-01-23T16:14:51.030 に答える
4

あなたは持っていますunique_ptr

std::unique_ptr<int> ptr = createPtr(2);

次に、そのコピーをベクターに入れます。

vec.push_back(ptr);

unique_ptrこれで、同じ値を持つ 2 つの ができました。それが許されるなら、それはユニークではありません。

于 2013-01-24T14:58:08.073 に答える