6

概念的には次のような例外クラス階層を作成しようとしています。

#include <iostream>
#include <stdexcept>

class ExceptionBase : public std::runtime_error {
public: 
    ExceptionBase( const char * msg ) : std::runtime_error(msg) {}
};

class OperationFailure : virtual public ExceptionBase {
public: 
    using ExceptionBase::ExceptionBase;
};

class FileDoesNotExistError : virtual public ExceptionBase {
public: 
    using ExceptionBase::ExceptionBase;
};

class OperationFailedBecauseFileDoesNotExistError
    : public OperationFailure, FileDoesNotExistError {
public: 
    using ExceptionBase::ExceptionBase; // does not compile
};

int main() {
    OperationFailedBecauseFileDoesNotExistError e("Hello world!\n");

    std::cout << e.what();
}

ExceptionBaseすべてのコンストラクターは、クラスのコンストラクターと同じに見える必要があります。派生した例外は、その型に関してのみ異なります。それ以外の追加機能はありません。上記のコードで言及されている最後の例外タイプにも、これらのコンストラクターが必要です。これは、C++11 標準の継承コンストラクター機能を使用して可能ですか? それが不可能な場合: 代替手段は何ですか?

(ちなみに: 上記のコードでは、 クラスOperationFailureFileDoesNotExistErrorは gcc 4.8 ではコンパイルされませんでしたが、clang 3.4 でコンパイルされました。明らかに、gcc は仮想ベースの継承コンストラクターを拒否します。誰がここにいるのかを知ることは興味深いでしょう。両方のコンパイラーがクラスOperationFailedBecauseFileDoesNotExistErrorを拒否しました。継承するコンストラクターは直接のベースから継承しないためです。)

4

2 に答える 2

1

コンストラクターの継承は、指定したすべてのコンストラクターにラッパー関数を導入するようなものです。あなたの場合、両方の特定のコンストラクターを呼び出す必要がありますOperationFailureFileDoesNotExistError、導入されたラッパーはそれらのいずれかのみを呼び出します。


最新の C++11 ドラフト(セクション 12.9)を確認しましたが、実際には明示的にカバーされていません。

于 2013-10-16T10:04:01.077 に答える