23

定義した列挙型へのコマンドライン入力を検証しようとしていますが、コンパイラエラーが発生します。作業の例として、Boostのprogram_optionsで複雑なオプションを処理するを使用しました。

namespace po = boost::program_options;

namespace Length
{

enum UnitType
{
    METER,
    INCH
};

}

void validate(boost::any& v, const std::vector<std::string>& values, Length::UnitType*, int)
{
    Length::UnitType unit;

    if (values.size() < 1)
    {   
        throw boost::program_options::validation_error("A unit must be specified");
    }   

    // make sure no previous assignment was made
    //po::validators::check_first_occurence(v); // tried this but compiler said it couldn't find it
    std::string input = values.at(0);
    //const std::string& input = po::validators::get_single_string(values); // tried this but compiler said it couldn't find it

    // I'm just trying one for now
    if (input.compare("inch") == 0)
    {
        unit = Length::INCH;
    }   

    v = boost::any(unit);
}

// int main(int argc, char *argv[]) not included

そして、必要以上のコードを含めることを惜しまないために、次のようにオプションを追加しています。

po::options_description config("Configuration");
config.add_options()
    ("to-unit", po::value<std::vector<Length::UnitType> >(), "The unit(s) of length to convert to")
;

コンパイラエラーが必要な場合は投稿できますが、質問をシンプルに見せたいと思っていました。例を探してみましたが、実際に見つけた他の例は、BoostWebサイトのexamples/regex.cppだけでした

  1. 私のシナリオと見つかった例の違いはありますか?ただし、私のシナリオは列挙型であり、他のシナリオは構造体です。編集:私のシナリオでは、カスタムバリデーターのオーバーロードは必要ありませんでした。
  2. 列挙型のvalidateメソッドをオーバーロードする方法はありますか?編集:必要ありません。
4

1 に答える 1

32

あなたの場合、次に示すように、からoperator>>を抽出するためにオーバーロードする必要があります。Length::Unitistream

#include <iostream>
#include <boost/foreach.hpp>
#include <boost/program_options.hpp>

namespace Length
{

enum Unit {METER, INCH};

std::istream& operator>>(std::istream& in, Length::Unit& unit)
{
    std::string token;
    in >> token;
    if (token == "inch")
        unit = Length::INCH;
    else if (token == "meter")
        unit = Length::METER;
    else 
        in.setstate(std::ios_base::failbit);
    return in;
}

};

typedef std::vector<Length::Unit> UnitList;

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

    namespace po = boost::program_options;
    po::options_description options("Program options");
    options.add_options()
        ("to-unit",
             po::value<UnitList>(&units)->multitoken(),
             "The unit(s) of length to convert to")
        ;

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, options), vm);
    po::notify(vm);

    BOOST_FOREACH(Length::Unit unit, units)
    {
        std::cout << unit << " ";
    }
    std::cout << "\n";

    return 0;
}

カスタムバリデーターは必要ありません。

于 2011-03-06T18:43:59.010 に答える