質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.35%
C++

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

Q&A

解決済

1回答

914閲覧

オブジェクトのコピーを返せない。

退会済みユーザー

退会済みユーザー

総合スコア0

C++

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

0グッド

0クリップ

投稿2020/03/16 18:52

編集2020/03/16 18:56

質問内容

下記のコード中にある構造体Aの
operator+の戻り値を
オブジェクトのコピーにして返したいのですが
そうするとコンパイルエラーが発生します。

エラーログではコピーコンストラクタの引数が一致しないと
記載されているようなので試しに
const A&型を引数にするコピーコンストラクタではなく
A&型を引数にしたコピーコンストラクタを追加してみましたが
追加する前と同じエラーログを吐くコンパイルエラーが発生しました。

そこで2つの質問がございます。
・どのように書けばオブジェクトのコピーを返せるようになるのでしょうか?
・なぜこのような問題が発生するのでしょうか?

どうかよろしくお願いします。

ちなみにA&やA&&を返すのならコンパイルエラーは発生しませんでしたが
operator+に関してはコピーを返せるようにしたいので質問させて頂きました。

問題の発生したコード

c++

1#include <iostream> 2using namespace std; 3 4struct A{ 5 int var; 6 7 A(){ 8 this->var = 0; 9 } 10 11 explicit A(const A& copy){ 12 *this=copy; 13 } 14 15 A& operator=(const A& copy){ 16 this->var = copy.var; 17 return *this; 18 } 19 20 A& operator=(const int arg){ 21 this->var = arg; 22 return *this; 23 } 24 25 // 26 // 問題の発生した部分 27 // 28 A operator+(const A& arg)const{ 29 A a; 30 a.var = this->var + arg.var; 31 return a; 32 } 33}; 34 35ostream& operator<<(ostream& os, const A& arg)noexcept{ 36 os << (arg.var); 37 return os; 38} 39 40int main(void){ 41 A a1; 42 A a2; 43 44 a1 = 1; 45 a2 = 2; 46 47 cout << (a1+a2) << endl; 48} 49

エラーログ

terminal

1a.cpp: In member function ‘A A::operator+(const A&)’: 2a.cpp:30:16: error: no matching function for call to ‘A::A(A&)’ 3 return a; 4 ^ 5a.cpp:7:5: note: candidate: A::A() 6 A(){ 7 ^ 8a.cpp:7:5: note: candidate expects 0 arguments, 1 provided 9 10

補足情報(FW/ツールのバージョンなど)

OS:LinuxMint18.3 Cinammon
コンパイラ:g++ 7.4.0

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

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

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

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

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

hoshi-takanori

2020/03/16 19:42

コピーコンストラクターに explicit が付いてるからでは?
guest

回答1

0

ベストアンサー

まさに妥当なコピーコンストラクタが無いのでエラーになっているというだけです。

コピーコンストラクタは自分自身と同じ型の参照を受け取るメンバ関数で、なおかつ explicit であってはいけません。 質問中の例であれば explicit を消すだけでも通ります。

explicit は暗黙に呼び出されることを抑止する指定です。 「これはコピーコンストラクタではなく普通に引数を一個受け取るコンストラクタだよ!」ということをあなたは宣言しています。 何の意図で explicit を付けているのでしょうか?

投稿2020/03/16 19:50

SaitoAtsushi

総合スコア5684

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

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

退会済みユーザー

退会済みユーザー

2020/03/16 20:10

ご回答ありがとうございます。 仰る通りexplicitを外したらコンパイルが通りました。 explicitを付けている理由につきましては http://starpentagon.net/life/2017/01/explicit_constructor/ ここの例のように意図しない挙動を防ぐために 普段から引数が1つのコンストラクタにはexplicitをつけることを 習慣付けていた事が原因です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問