62

C++11の新しいヘッダーに関する一連の思慮深いブログ投稿を読みました。<system_error>ヘッダーはerror_code、操作(システムコールなど)によって返される特定のエラー値を表すクラスを定義することを示しています。ヘッダーsystem_errorは、例外クラス(から継承runtime_exception)であり、sをラップするために使用されるクラスを定義することを示していerror_codesます。

私が知りたいのは、実際にシステムエラーをからに変換してerrnoスローsystem_errorできるようにする方法です。たとえば、POSIXopen関数は-1を返し、設定することでエラーを報告しますerrno。したがって、例外をスローしたい場合は、以下のコードをどのように完了する必要がありますか?

void x()
{
    fd = open("foo", O_RDWR);
    if (fd == -1)
    {
        throw /* need some code here to make a std::system_error from errno */;
    }
}

私はランダムに試しました:

errno = ENOENT;
throw std::system_error();

ただし、結果として生じる例外は、what()が呼び出されたときに情報を返しません。

できることはわかっていますが、新しいヘッダーthrow errno;を使用して、正しい方法で実行したいと思います。<system_error>

そのためのコンストラクターがあり、その引数としてsystem_error単一を取りerror_codeます。したがって、私が変換できるのであればerrnoerror_code残りは明白なはずです。

これは本当に基本的なことのように思われるので、なぜそれに関する良いチュートリアルが見つからないのかわかりません。

重要な場合は、ARMプロセッサでgcc4.4.5を使用しています。

4

2 に答える 2

61

あなたは正しい方向に進んでいます。エラーコードとstd::generic_categoryオブジェクトをstd::system_error コンストラクターに渡すだけで、機能するはずです。

例:

#include <assert.h>
#include <errno.h>
#include <iostream>
#include <system_error>

int main()
{
    try
    {
        throw std::system_error(EFAULT, std::generic_category());
    }
    catch (std::system_error& error)
    {
        std::cout << "Error: " << error.code() << " - " << error.what() << '\n';
        assert(error.code() == std::errc::bad_address);
    }
}

私のシステムでの上記のプログラムからの出力は

エラー:generic:14-不正なアドレス
于 2012-08-29T05:48:29.397 に答える
6

受け入れられた優れた回答に追加するために、3番目の引数のコンテキスト情報(失敗したファイル名など)でエラーメッセージを充実させることができます。

std::string file_name = "bad_file_name.txt";
fd = open(file_name, O_RDWR);
if (fd < 0) {
    throw std::system_error(errno, std::generic_category(), file_name);
}

次に、キャッチe.what()されると、たとえば次のように戻ります。

bad_file_name.txt: file not found
于 2021-04-18T20:07:22.240 に答える