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

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

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

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

Q&A

解決済

2回答

3668閲覧

C++のコンパイル時にエラーが出る

yu_89

総合スコア34

C++

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

0グッド

0クリップ

投稿2022/03/17 11:00

解決したいこと

c++で添付したソースコードをコンパイルすると以下のエラーメッセージが出て実行できません。
柴田望洋の「c++で学ぶオブジェクト指向プログラミング」を参考にしています。
調べて色々試したのですが、解決しません。何が原因なのでしょうか。

発生している問題・エラーメッセージ

MyException.cpp:12:23: error: looser throw specifier for ‘virtual const char* MyException::what() const’ 12 | virtual const char* what() const { return "マイ例外"; } | ^~~~ In file included from /usr/include/c++/9/system_error:41, from /usr/include/c++/9/bits/ios_base.h:46, from /usr/include/c++/9/ios:42, from /usr/include/c++/9/ostream:38, from /usr/include/c++/9/iostream:39, from MyException.cpp:1: /usr/include/c++/9/stdexcept:143:5: note: overridden function is ‘virtual const char* std::logic_error::what() const noexcept’ 143 | what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW; | ^~~~ MyException.cpp: In function ‘void work(int)’: MyException.cpp:19:46: error: no matching function for call to ‘std::exception::exception(const char [16])’ 19 | case 1: throw exception("exception例外"); | ^ In file included from /usr/include/c++/9/exception:38, from /usr/include/c++/9/ios:39, from /usr/include/c++/9/ostream:38, from /usr/include/c++/9/iostream:39, from MyException.cpp:1: /usr/include/c++/9/bits/exception.h:68:5: note: candidate: ‘constexpr std::exception::exception(std::exception&&)’ 68 | exception(exception&&) = default; | ^~~~~~~~~ /usr/include/c++/9/bits/exception.h:68:15: note: no known conversion for argument 1 from ‘const char [16]’ to ‘std::exception&&’ 68 | exception(exception&&) = default; | ^~~~~~~~~~~ /usr/include/c++/9/bits/exception.h:66:5: note: candidate: ‘constexpr std::exception::exception(const std::exception&)’ 66 | exception(const exception&) = default; | ^~~~~~~~~ /usr/include/c++/9/bits/exception.h:66:15: note: no known conversion for argument 1 from ‘const char [16]’ to ‘const std::exception&’ 66 | exception(const exception&) = default; | ^~~~~~~~~~~~~~~~ /usr/include/c++/9/bits/exception.h:63:5: note: candidate: ‘std::exception::exception()’ 63 | exception() _GLIBCXX_NOTHROW { } | ^~~~~~~~~ /usr/include/c++/9/bits/exception.h:63:5: note: candidate expects 0 arguments, 1 provided ---

該当のソースコード

c++

1#include <iostream> 2#include <exception> 3#include <stdexcept> 4 5using namespace std; 6 7class MyException : public logic_error 8{ 9public: 10 MyException() : logic_error("マイ例外") {} 11 12 virtual const char* what() const { return "マイ例外"; } 13}; 14 15void work(int sw) 16{ 17 switch(sw) 18 { 19 case 1: throw exception("exception例外"); 20 case 2: throw logic_error("logic_error例外"); 21 case 3: throw MyException(); 22 } 23} 24 25void test(int sw) 26{ 27 try 28 { 29 work(sw); 30 } 31 32 catch(const MyException& e) 33 { 34 cout << e.what() << "を補足。対処完了!!\n"; 35 } 36 37 catch(const logic_error& e) 38 { 39 cout << e.what() << "を補足。対処断念!!\n"; 40 throw; 41 } 42 43 catch(const exception& e) 44 { 45 cout << e.what() << "を補足。対処断念!!\n"; 46 throw "ABC"; 47 } 48} 49 50int main() 51{ 52 int sw; 53 54 cout << "sw: "; 55 cin >> sw; 56 57 try 58 { 59 test(sw); 60 } 61 62 catch(const logic_error& e) 63 { 64 cout << e.what() << "を補足。\n"; 65 } 66 67 catch(const char* e) 68 { 69 cout << e << "を補足。\n"; 70 } 71}

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

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

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

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

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

yu_89

2022/03/18 04:43

ご回答いただきありがとうございます。 回答を頂けたおかげで"what()"に関するエラーは解決することが出来ましたが、19行目の "case 1: throw exception("exception例外");"で出ている"no matching function for call to std::exception::exception(const char [16])"のエラーは解決できていません。どなたかわかる方,このエラーの解決方法を教えていただけないでしょうか。このエラーについてググってみてもあまりピンとこなくて。
jbpb0

2022/03/20 11:51

> 無事、解決することが出来ました。 解決したのなら、SaitoAtsushiさんの回答をベストアンサーにしましょう
yu_89

2022/03/20 13:18

ベストアンサーにするのを忘れていました。すみません。ご指摘ありがとうございます。
guest

回答2

0

ベストアンサー

C++11 の 15.4.5 には以下のような記述があります。

If a virtual function has an exception-specification, all declarations, including the definition, of any function that overrides that virtual function in any derived class shall only allow exceptions that are allowed by the exception-specification of the base class virtual function.
(仮想関数が例外指定を持つ場合、派生クラスでその仮想関数を上書きする関数の (定義を含めた) すべての宣言は、その基底クラスの仮想関数の例外指定によって許された例外だけを許さなければならない。)

cpp

1struct B { 2 virtual void f() throw (int, double); 3 virtual void g(); 4}; 5 6struct D: B { 7 void f(); // ill-formed 8 void g() throw (int); // OK 9};

The declaration of D::f is ill-formed because it allows all exceptions, whereas B::f allows only int and double.
(宣言 D::f は、 B::fint 及び double だけを許すにもかかわらず、全ての例外を許す記述となっているので不適格となる。)

そして std::exception::what

cpp

1virtual const char* what() const noexcept;

ということになっていて、要するに例外を全く送出しないのでオーバーライドで置き換える場合においてもこれより多くの例外が送出される可能性があってはならない、つまり同様に例外を送出しないような指定 (noexcept) を付ける必要があります。


もうひとつの問題としては、 std::exception のコンストラクタとしてはデフォルトコンストラクタとコピーコンストラクタしか用意されていません。

つまり質問者が提示しているコードのように引数を渡して構築することは出来ません。

cpp

1// ↓ 文字列を渡すことは出来ない!! 2exception("exception例外");

投稿2022/03/18 04:58

SaitoAtsushi

総合スコア5444

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

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

yu_89

2022/03/18 05:56

ご回答いただきありがとうございます。無事、解決することが出来ました。
guest

0

とりあえずエラーメッセージの文言を用いて適当に "looser throw specifier" とかでググってみてはどうですか?

「例外指定が基本クラスよりも弱いのはダメだ」って言われていると見えますが.

std::exception::what() は noexcept がついてるみたいなので,それを継承している側でもそうしないといかんのでは.

投稿2022/03/17 11:19

編集2022/03/17 11:22
fana

総合スコア11654

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

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

yu_89

2022/03/18 04:44

ご回答いただきありがとうございます。"what()"に関するエラーは解決することが出来ました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問