コードにスタイルの問題があり、他の人が遭遇したのではないかと思います。デフォルトのコンストラクターがないか、(パフォーマンスとスタイルの理由で) 呼び出したくないデフォルトのコンストラクターがあるクラスがあるとします。例として、これが File オブジェクトであるとしましょう。
ここで、削除するファイル名のリストを含むファイルがあるとしましょう...そして、次のことをしたいと思います:
File f("foo");
for (const string& filenameToDelete : f.Lines())
File(filenameToDelete).Delete();
File は、コンストラクターまたは Delete 関数で FileNotFound をスローできます。私のコードは、ファイルの削除に最初に失敗したときにスローする必要がありますが、ファイル「foo」が存在しない場合はスローしてはなりません (ファイルがないということは、削除するものが何もないことを意味します)。
私はこのようなものを書くことができればいいのに:
try { File f("foo"); } catch (FileNotFound) { return; }
for (const string& filenameToDelete : f.Lines())
File(filenameToDelete).Delete();
しかし、それは明らかにコンパイルされません。私はこれを行うことができます:
unique_ptr<File> f;
try { f.reset(new File("foo")); } catch (FileNotFound) { return; }
for (const string& filenameToDelete : f->Lines())
File(filenameToDelete).Delete();
しかし、そうでなければスタックに割り当てられる可能性のある変数にメモリ割り当てを行う必要があるという事実がやや嫌いです...
ヒープ割り当てを行わないというやや恣意的な制約でコードを書きたい場合は、次の方法しか考えられません。
struct FileNotFoundToRethrow : public FileNotFound {};
try
{
File f("foo");
try
{
for (const string& filenameToDelete : f.Lines())
File(filenameToDelete).Delete();
}
catch (FileNotFound)
{
throw FileNotFoundToRethrow();
}
}
catch (FileNotFoundToRethrow) { throw; }
catch (FileNotFound) { return; }
私はこれがかなり醜いと思います.最初の行でスローされた FileNotFound 例外を処理することだけが目的であることがわかりません...もっと良い方法はありますか?