65888


## 概要

Visual Studioで開発中に発生したC2280コンパイルエラーが発生する理由と解決できた理由を教えてください。

## 詳細

簡単な画像処理を実行するコード作成中にC2280コンパイルエラーが発生しました。  
コンパイラのエラーメッセージに従ってコードを修正するとエラーが発生しなくなり、正常に動作しているように見えました。  
しかし、いったいどのような理由でエラーが発生して、結局解決できたのかがわからずもやもやしている状態です。

## コード

[code]

    #include <iostream>
    #include <memory>
    #include "opencv2\opencv.hpp"
    
    class CImage {
    public:
        CImage() = delete;  //引数無しのコンストラクタは禁止したい
        CImage(const cv::Mat& inImage) :m_MatImage(inImage) {};  //必ず引数有のコンストラクタを実行してほしい
        ~CImage(){m_MatImage.release();};
    
        cv::Mat getMatImage() const { return m_MatImage.clone(); };
    
    private:
        cv::Mat m_MatImage;
    };
    
    class CParameter {
    public:
        CParameter() :m_ReferenceImagePtr(nullptr) {};
        CParameter(const CParameter &);  //この行を挿入することでエラーを回避できる No1
        //CParameter(const CParameter &) =default;  //=defaultにするとエラーは残ったまま No2
        ~CParameter() { m_ReferenceImagePtr.reset(); }; //デストラクタを省略するとコピーコンストラクタ無しで もエラーを回避できる No3
    
        void setImage(const CImage& inImage)
        {
            m_ReferenceImagePtr = std::make_unique<CImage>(inImage);
        };
        cv::Mat getImage()
        {
            return m_ReferenceImagePtr->getMatImage();
        };
    
    private:
        std::unique_ptr<CImage> m_ReferenceImagePtr;
    };
    
    void main() {
        cv::Mat img = cv::Mat::zeros(100, 100, CV_8UC1);
        CImage image = CImage(img);
        CParameter parameter = CParameter(); //C2280エラー発生個所
        //何らかの画像処理が続く...
    }
    
[/code]

エラーメッセージを抜粋したものが以下になります

> error C2280: 'CParameter::CParameter(const CParameter &)':  
>  削除された関数を参照しようとしています  
>  コンパイラが 'CParameter::CParameter' をここに生成しました。

## 質問

コードのコメント中のナンバー毎に質問があります  
No1: どうしてコピーコンストラクタを追加するとC2280エラーが解消されるのか  
No2: コピーコンストラクタの追加で=defaultの場合はエラーが解消されないがNo1との違いは何か  
No3: デストラクタを除外するとコピーコンストラクタなしでもエラーが発生しない理由は何か

## 環境

開発環境: Visual Studio 2015 14.0.25431.01 Update3  
OpenCV: Ver3.4.3

## 参考にした情報

[エラーに関するMicrosoftのドキュメントページ](https://docs.microsoft.com/ja-jp/cpp/error-
messages/compiler-errors-1/compiler-
error-c2280?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev16.query%3FappId%3DDev16IDEF1%26l%3DJA-
JP%26k%3Dk\(C2280\)%26rd%3Dtrue&view=vs-2019)  
[C++のdefault/deleteの参考](https://cpprefjp.github.io/lang/cpp11/defaulted_and_deleted_functions.html)


CC BY-SA 4.0
2020-04-23T08:37:21.813
65885
2020-04-23T09:26:12.307
19500
question
c++ visual-studio c++11
C2280エラーが発生した理由と解決できた理由を知りたい


`std::unique_ptr<CImage>` はコピーコンストラクタを持たないので `CParameter`
もデフォルトコピーコンストラクタを利用できません。

No1とNo3については、C++11～C++14ではコピーコンストラクタ呼び出しが省略されることもされないこともあるため、質問のプログラムは環境依存です。
<https://ja.cppreference.com/w/cpp/language/copy_elision>

No2はデフォルトでないコピーコンストラクタは作成可能なので、コピーコンストラクタを宣言すればコンパイル時のエラーは回避出来て、(コピーコンストラクタを定義しなければ)リンク時にエラーになります。


CC BY-SA 4.0
2020-04-23T09:26:12.307
65888
2020-04-23T09:26:12.307
241
65885
answer