🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

968閲覧

菱型継承にて、set()は存在するのにoperator=だけが削除されるのは何故?

asobinin

総合スコア69

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/10/24 16:42

編集2019/10/25 04:42

菱型継承を利用してpropertyのようなものを実装しようと試みたのですが、原因が分からないエラーに悩まされています。

full_options_propertyを宣言しoperator =を利用しようとしたところ、「C2280 'full_options_property<int> &full_options_property<int>::operator =(const full_options_property<int> &)': 削除された関数を参照しようとしています」
というエラーが発生してしまいました。
ところが、引数も処理も全く同じset()は削除されずに問題なく使用できます。
何故operator =のみが削除されてしまっているのでしょうか?

full_options_propertyのコピーコントラスタにて、otherがget_options_propertyの機能しかアクセスできないということにも関連があるのでしょうか?

開発環境 OS:Windows10 Home コンパイラ: Visual Studio2019
(WandBoxでも試してみましたが、同様のエラーが出ました)

Cpp

1#include <utility> 2 3// アクセス権限を持たないプロパティ 4template <class T> 5class none_options_property { 6protected: // メンバ変数 7 T m_value; 8public: // コンストラクタ 9 none_options_property() = default; 10 none_options_property(const T& value) : m_value(value) {} 11 none_options_property(T&& value) : m_value(std::move(value)) {} 12 none_options_property(const none_options_property& other) : m_value(other.m_value) {} 13 none_options_property(none_options_property&&) = default; 14}; 15 16// getオプションを持ったプロパティ 17template <class T> 18class get_options_property : virtual public none_options_property<T> { 19public: // コンストラクタ 20 using none_options_property<T>::none_options_property; 21 //get_options_property(const get_options_property& other) : none_options_property<T>(other.m_value) {} 22public: // メンバ関数 23 const T& get() const { return this->m_value; } 24 operator const T& () const { return this->m_value; } 25}; 26 27// setオプションを持ったプロパティ 28template <class T> 29class set_options_property : virtual public none_options_property<T> { 30public: // コンストラクタ 31 using none_options_property<T>::none_options_property; 32 //set_options_property(const set_options_property& other) : none_options_property<T>(other.m_value) {} 33public: // メンバ関数 34 auto& set(const T& value) { this->m_value = value; return *this; } 35 auto& set(T&& value) { this->m_value = std::move(value); return *this; } 36 auto& set(const none_options_property<T>& other) { this->m_value = other.m_value; return *this; } 37 auto& operator =(const T& value) { this->m_value = value; return *this; } 38 auto& operator =(T&& value) { this->m_value = std::move(value); return *this; } 39 auto& operator =(const none_options_property<T>& other) { this->m_value = other.m_value; return *this; } 40}; 41 42// get, setオプションを持ったプロパティ 43template <class T> 44class full_options_property final : public get_options_property<T>, public set_options_property<T> { 45public: // コンストラクタ 46 full_options_property() : none_options_property<T>(), get_options_property<T>(), set_options_property<T>() {} 47 full_options_property(const T& value) : none_options_property<T>(value), get_options_property<T>(value), set_options_property<T>(value) {} 48 full_options_property(T&& value) : none_options_property<T>(std::move(value)), get_options_property<T>(std::move(value)), set_options_property<T>(std::move(value)) {} 49 full_options_property(const full_options_property& other) : none_options_property<T>(other), get_options_property<T>(other), set_options_property<T>(other) {} 50}; 51 52int main() 53{ 54 full_options_property<int> t(1134); 55 t.set(810); 56 t = 2; 57 58 return 0; 59}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは。

clangでやってみると、懇切丁寧なエラーメッセージが表示されました。たぶんconceptの威力ですね。
結論としては、none_options_propertyでムーブ代入演算子が定義されているからコピー代入演算子が暗黙的に削除され、それが原因でfull_options_property のコピー代入演算子が暗黙的に削除されているようです。

このエラー・メッセージは素晴らしい!!

投稿2019/10/24 18:31

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

asobinin

2019/10/24 23:25

なるほど、Tがproperty型の時に矛盾があるから、コンパイラが削除したということですね! それにしても、コンパイラによってエラーメッセージもこれほどにまで変わるのですね… wandbox=gccと思っておりましたが、こうしてみると何故wandboxが支持を得ているのかがよくわかりますね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問