1. ホーム
  2. c++

[解決済み] std::unique_ptr を関数に渡すには?

2022-06-14 01:17:29

質問

どのようにすれば std::unique_ptr を関数に渡すことはできますか?例えば、次のようなクラスがあるとします。

class A
{
public:
    A(int val)
    {
        _val = val;
    }

    int GetVal() { return _val; }
private:
    int _val;
};

以下はコンパイルできません。

void MyFunc(unique_ptr<A> arg)
{
    cout << arg->GetVal() << endl;
}

int main(int argc, char* argv[])
{
    unique_ptr<A> ptr = unique_ptr<A>(new A(1234));
    MyFunc(ptr);

    return 0;
}

なぜ std::unique_ptr を関数に渡すことができないのでしょうか?確かにこれはコンストラクタの主な目的なのでしょうか。それとも C++ 委員会は、私が生の C スタイルのポインタに戻り、このようにそれを渡すことを意図していたのでしょうか。

MyFunc(&(*ptr)); 

そして何より不思議なのは、なぜこの渡し方でOKなのか?恐ろしく矛盾しているように思えます。

MyFunc(unique_ptr<A>(new A(1234)));

どのように解決するのですか?

基本的には2つの方法があります。

スマートポインタを参照で渡す

void MyFunc(unique_ptr<A> & arg)
{
    cout << arg->GetVal() << endl;
}

int main(int argc, char* argv[])
{
    unique_ptr<A> ptr = unique_ptr<A>(new A(1234));
    MyFunc(ptr);
}

スマートポインタを関数の引数に移動する

この場合、アサーションは保持されることに注意してください!

void MyFunc(unique_ptr<A> arg)
{
    cout << arg->GetVal() << endl;
}

int main(int argc, char* argv[])
{
    unique_ptr<A> ptr = unique_ptr<A>(new A(1234));
    MyFunc(move(ptr));
    assert(ptr == nullptr)
}