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

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

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

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

C++

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

Q&A

解決済

1回答

1429閲覧

【C++】条件により異なる型の戻り値を返したい

Kenichir

総合スコア28

Visual C++

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

C++

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

0グッド

0クリップ

投稿2020/04/16 04:49

編集2020/04/17 00:20

【実現したいこと】戻り値の型を計算結果によって変化させたい

質問を見ていただきありがとうございます.
C++の勉強のため,下記のように二次関数を表現するクラスと解を計算する関数を書いています.
二次関数ax^2 + bx + c = 0において,b^2 - 4 * a * cの値により解が実数か虚数か,また解の個数も変化しますが,これをどう表現すればいいかわからず困っております.
下記のようにコードを書いてみましたが,auto Solve();のようにしても戻り値の型が条件によって変化するのでコンパイルエラーとなってしまいます.

###コード
ハマっている部分にコメントで// 【疑問】と付けておきました.
この部分について教えていただきたいです.

C++

1// 二次関数のためのクラス 2class QuadraticEq 3{ 4 // a x^2 + b x + c = 0の係数を保持する変数 5 float a; 6 float b; 7 float c; 8 // 【疑問】解xも保存しておいた方が良いのか? 9public: 10 // コンストラクタ 11 QuadraticEq(float in_a, float in_b, float in_c) 12 { 13 a = in_a; 14 b = in_b; 15 c = in_c; 16 }; 17 // 【疑問】ここの型宣言がautoでは解が二つの時もあるのでうまくいかない 18 auto Solve(); 19}; 20 21auto QuadraticEq::Solve() 22{ 23 // aが0以外なら二次方程式 24 if(a != 0) 25 { 26 // SqrtPart : 根号の中を計算 27 float SqrtPart = b*b - 4*a*c; 28 // 解が実数で二つの時 29 if(SqrtPart > 0) 30 { 31 float x[2]; 32 x[0] = (-b - sqrt(SqrtPart)) / (2 * a); 33 x[1] = (-b + sqrt(SqrtPart)) / (2 * a); 34 // 【疑問】そもそも配列を返すことはできないようですが,とりあえず... 35 return x; 36 } 37 // 解が実数かつ重解 38 else if (SqrtPart = 0) 39 { 40 float x = -b / 2 * a; 41 return x; 42 } 43 // 解が複素数 44 else 45 { 46 // 【疑問】できれば複素数2つを返したい 47 } 48 } 49 // aが一次方程式 50 else 51 { 52 float x = -c / b; 53 } 54 return x; 55};

C++について問題を解決するために何を調べたら良いかもいまいちわからず苦戦しています.
できる限り疑問点をまとめたつもりですが,どういう風に返したいのかなど曖昧でしたら補足させていただきます.
どうぞよろしくお願いいたします.

【解決コード】追記

ご回答の通り,vectorを用いればうまくいったので修正した最終的なコードを載せておきます.
かなり初歩的なところだとは思いますが,同じようなところで詰まっている誰かの参考になればと思います.

#include <iostream> #include <string> #include <cmath> #include <vector> #include <complex> using namespace std; class QuadraticEq { // a x^2 + b x + c = 0のための変数 float a; float b; float c; // 解を保存しておく vector<complex<float>> x; public: QuadraticEq(float in_a, float in_b, float in_c) { a = in_a; b = in_b; c = in_c; Solve(); }; // 解を計算して内部変数に保存する関数 void Solve(); void Disp(); }; ///////////// main ///////////////// int main(int argc, const char * argv[]) { // insert code here... QuadraticEq EQ(1, 1, -6); EQ.Disp(); return 0; } void QuadraticEq::Solve() { // aが0以外なら二次方程式 if(a != 0) { // qrtPart : 根号の中を計算 float SqrtPart = b*b - 4*a*c; // 解が実数で二つの時 if(SqrtPart > 0) { // 実部の計算 float Smallerx = (-b - sqrt(SqrtPart)) / 2 * a; float Largerx = (-b + sqrt(SqrtPart)) / 2 * a; x.push_back(complex<float>(Smallerx,0)); x.push_back(complex<float>(Largerx,0)); } // 解が実数かつ重解 else if (SqrtPart == 0) { float RealPart = -b / 2 * a; x.push_back(complex<float>(RealPart,0)); } // 解が複素数 else { // 実部の計算 float RealPart = - b / (2 * a); // 虚部の計算 float ImagPart = SqrtPart / (2 * a); x.push_back(complex<float>(RealPart, -ImagPart)); x.push_back(complex<float>(RealPart, ImagPart)); } } // aが一次方程式 else { x.push_back(complex<float>(-c / b, 0)); } }; void QuadraticEq::Disp() { for (int i = 0; i < x.size(); i++) { // 虚部の値によって表示を変える if (x[i].imag() > 0) { cout << x[i].real() << " + " << x[i].imag() << endl; } else if (x[i].imag() == 0) { cout << x[i].real() << endl; } else { cout << x[i].real() << x[i].imag() << endl; } } };

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

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

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

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

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

guest

回答1

0

ベストアンサー

できるだけ汎用的にするには、「複素数の配列(もしくはvectorなどそれに準じる構造)」を返すとしておけば問題ありません。

解が1つの場合も「1個だけの配列」にできますし、実数も「虚部が0の複素数」として表現可能です。

投稿2020/04/16 04:52

maisumakun

総合スコア145184

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

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

Kenichir

2020/04/16 05:03

サイズが2つの複素数の配列を常に返すということですね! 解が1つの場合も「1個だけの配列」にできるということですが,それは配列2つに同じ値を代入して返すということでしょうか?
maisumakun

2020/04/16 05:05

> 配列2つに同じ値を代入して返す 「重複度2の重解」だとわかりやすいですし、それもありかもしれないですね(vectorなら個数に関わらずおなじvectorとして扱えます)。
episteme

2020/04/16 08:31

std::vector<float> (要素数可変のfloat列)返せばいいじゃん、ってこと。 要素数0なら解なし、1なら重解 と解釈できるから。
Kenichir

2020/04/17 00:24

ご回答の通りやってみたらうまく行きました. コードの書き方が汚いかもしれませんがこれからうまくなっていこうと思います. 追記に解決したコードを載せておきました. ありがとうございます,調べればわかるだろとイライラさせてしまったようですね,申し訳ありません. vectorの存在を知らない私にとっては調べることが難しかったのですが,ここでvectorの存在や詳しいコメント,捕捉までしてくださる方がいて本当に感謝しております. ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問