10

以下のコードでは、プログラム オプションを使用して、コマンドラインまたはファイルからパラメーターを読み取りました。さらに、ConfigProxy::setConfigを使用して実行時にプログラムでオプションを設定できます。

po::options_description desc("Allowed options");
desc.add_options()
    ...
    ("compression", po::value<int>(), "set compression level");

po::variables_map vm;

class ConfigProxy
{
     template< typename T>
     void setConfig( const std::string key, const T value ){
          ... // check if the key exists in variable map "vm"

          // key exists, set the value
          runtimeConfig[key] = po::variable_value( boost::any(value), false);
     }

     po::variable_value& operator[] (const std::string key) const{
          ...
          // if exists in runtimeConfig return the value in runtimeConfig
          // of type program_options::variable_value
          ...
          // else return value in variable map "vm"
     }

     std::map<std::string, boost::program_options::variable_value> runtimeConfig;
}

ConfigProxy を介して、オプション値が取得されます

if( vm.count("compression") ){
    int value = proxyConfig["compression"].as<int>();
    ...
}

ただし、ユーザーが指定した「圧縮」オプションの値が間違ったタイプの場合、たとえば

configProxy.setConfig("compression", "12" );
...
int value = configProxy["compression"].as<int>(); // was set as string

その後、例外がスローされます

what():  boost::bad_any_cast: failed conversion using boost::any_cast

例外は、型キャストの問題を明確に示しています。しかし、このメッセージは、ユーザーがどのオプションがエラーの原因であるかを見つけるのにあまり役に立たないようです。

bad_any_cast例外をスローする代わりに、このタイプのエラーについてユーザーに通知するより良い方法はありますか?

- - - 編集 - - - - - - - - - - - - -

Luc Danton と Tony のおかげで、プログラム オプションがどのようにエラーを表示するかがわかりました。

void validate(boost::any& v,
              const std::vector< std::basic_string<charT> >& xs,
              T*, long)
{
    validators::check_first_occurrence(v);
    std::basic_string<charT> s(validators::get_single_string(xs));
    try {
        v = any(lexical_cast<T>(s));
    }
    catch(const bad_lexical_cast&) {
        boost::throw_exception(invalid_option_value(s));
    }
}

ロジックを実装することで、bad_any_cast 例外を取り除くことができると思います。

4

2 に答える 2

4

試してみましたか?

("compression", po::value<int>(), "set compression level");

注意してくださいpo::value<int>()。ここで、関連する値が type であることを指定しますint。ユーザーが Boost.ProgramOptions で変換できないものを渡すとint、プログラムは失敗し、次のエラー メッセージが表示されます。

error: in option 'compression': invalid option value

それがやはり図書館の役割の一つです。

あなたがしなければならないvm["compression"].as<int>()理由は、 の型がcompression関数呼び出し (括弧内のトリプレット) で指定されているためです。これは の戻り値の型に影響を与えることはできないvm["compression"]ため、動的な型のエミュレーションである必要があります。したがって、boost::any_cast_failed指定しなかったタイプを照会する場合は例外です。

于 2011-06-08T16:44:55.737 に答える
2

あなたはこれを置くことができません:

if( vm.count("compression") ){
    int value = vm["compression"].as<int>();
    ...
}

ブーストによってスローされた例外をキャッチするtry catchブロックでキャッチされ、作成したタイプの新しい例外をスロー (リロー) するか、にbad_any_castメッセージを書き込むことによって、独自のユーザーにメッセージを表示します。std::coutアプリケーションに大きく依存します。

それで:

try {
    if( vm.count("compression") ){
        int value = vm["compression"].as<int>();
        ...
    }
}
catch(const boost::bad_any_cast& ex)
{
//rethrow exception of your own to show to the user or print msg to std::cout
}
于 2011-06-08T16:28:37.390 に答える