12

これ(バージョン1.52.0)を私のアプリに統合してきましたが、上記のように問題に遭遇しました。

添付された例では、例外what()メソッドは常に%canonical_option%タグをそのまま保持しており、オプション名に置き換えられていません。

私はVS2008を使用しており、Unicode(オプション'none')を無効にし、プロジェクトから他のすべてのファイルを削除しました。これは、main.cppファイル内のこのコードのみです。

または、これをすべて間違って、正しいパラメータ名で例外メッセージをフォーマットするために呼び出す必要がある何かがありますか?

#include <boost/program_options.hpp>

namespace po = boost::program_options;

using namespace std;

int main(int argc, char* argv[])
{

    try {

        po::options_description optionalParams("optional");

        optionalParams.add_options() 
            ("log_severity,l", po::value<int>()->required(), "Minimum severity logging level")
            ("log_file,g", po::value<string>(), "Full path to log file")
            ;

        po::variables_map optMap;

        po::parsed_options parsed = po::command_line_parser(argc, argv)
            .options(optionalParams)
            .allow_unregistered()
            .run();

        po::store(parsed, optMap);

        po::notify(optMap);

    }
    catch(po::error e)
    {
        cout << e.what();
        return 0;
    }

    return 0;
}
4

2 に答える 2

20

ブーストコードを適切に参照した後、コードをもう一度見ると、答えがより明白になります。

catch(po::error e)
{
    cout << e.what();
    return 0;
}

する必要があります

catch(po::error& e)
{
    cout << e.what();
    return 0;
}

参照がなければ、ここでよく説明されている「オブジェクトのスライス」が得られます。

参照による例外のキャッチ

参照を使用しないということは、テンプレートの置換を行うオーバーライドされた「what」メソッドが失われることを意味します。

于 2012-11-19T09:55:46.363 に答える
3

これをデバッグするのに1時間費やしました-実際には興味深い動作です-コードの唯一の問題は、あなたがキャッチしているという事実だと思いますpo::error

catch(po::error e)
{
   cout << e.what() << std::endl;
    return 0;
}

キャッチを上の行に変更すると、これに

catch(po::required_option e)
{
   cout << e.what() << std::endl;
    return 0;
}

エラーメッセージとして次のように表示されます。

the option '--log_severity' is required but missing
Press any key to continue . . .

したがって、基本的には、置換は派生例外でのみ行われるように見えます。

編集:

いくつか読んだ後、実際に a をキャッチすることができstd::exception、 を呼び出したときに正しいメッセージが出力されますwhat()。すべての詳細については、以下のリンクを参照してください。

http://www.boost.org/doc/libs/1_52_0/libs/exception/doc/boost-exception.html

また、例外がスローされたときに何が起こっているかを診断するのに役立つ方法があることも発見しました。

#include <boost/exception/diagnostic_information.hpp>

...

catch(...)
{
    std::cerr << "Unhandled exception!" << std::endl <<
    boost::current_exception_diagnostic_information();
    return 0;
}

たとえば、上記のようにプログラムを変更すると、次のように出力されます。

Unhandled exception!
Throw location unknown (consider using BOOST_THROW_EXCEPTION)
Dynamic exception type: class boost::exception_detail::clone_impl<struct    
                               boost::exception_detail::error_info_injector<class 
                               boost::program_options::required_option> >
std::exception::what: the option '--log_severity' is required but missing
Press any key to continue . . .
于 2012-11-16T17:47:04.017 に答える