1. ホーム
  2. c++

[解決済み] 基底クラスへの一意なptrを受け取る関数の引数としての派生クラスへの一意なptr

2023-03-02 03:56:01

質問

私は unique_ptr を受け取る関数で、派生クラスに対して unique_ptr を取る関数の中で みたいな感じ。

class Base {};

class Derived : public Base {};

void f(unique_ptr<Base> const &base) {}

…

unique_ptr<Derived> derived = unique_ptr<Derived>(new Derived);
f(derived);

もし私が この答え を正しく理解していれば、このコードは動作するはずですが、以下のようなコンパイルエラーが発生します。

error C2664: 'f' : cannot convert parameter 1 from 'std::unique_ptr<_Ty>' to 'const std::unique_ptr<_Ty> &'パラメタ1を変換できません。

IntelliSense: "std::unique_ptr<Derived, std::default_delete<Derived>>" から "const std::unique_ptr<Base, std::default_delete<Base>" へのユーザ定義の適切な変換は存在しない。

もし私が f を取ると unique_ptr<Derived> const &derived を使用すると、それはうまく動作しますが、それは私が望むものではありません。

私は何か間違ったことをしているのでしょうか?これを回避するためにはどうしたらよいでしょうか。

Visual Studio 2012を使用しています。

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

3つの選択肢があります。

  1. 所有権を放棄する。これは、関数呼び出しの後、動的オブジェクトにアクセスできないローカル変数を残します; オブジェクトは呼び出し側に移されました。

    f(std::move(derived));
    
    
  2. の署名を変更する。 f :

    void f(std::unique_ptr<Derived> const &);
    
    
  3. 変数の種類を変更します。

    std::unique_ptr<base> derived = std::unique_ptr<Derived>(new Derived);
    
    

    またはもちろんただ。

    std::unique_ptr<base> derived(new Derived);
    
    

    あるいは、さらに

    std::unique_ptr<base> derived = std::make_unique<Derived>();
    
    
  4. 更新しました。 あるいは、コメントで推奨されているように、所有権をまったく移さないようにします。

    void f(Base & b);
    
    f(*derived);