boost :: program_options"polymorphic"参数

use*_*136 7 c++ boost boost-program-options

我想使用boost :: program_options创建一个可执行文件,可以调用如下:

./example --nmax=0,10  # nmax is chosen randomly between 0 and 10
./example --nmax=9     # nmax is set to 9
./example              # nmax is set to the default value of 10
Run Code Online (Sandbox Code Playgroud)

以最小的代码以类型安全的方式实现这一目标的最佳方法是什么?

use*_*136 1

我在这里发布这段代码,希望它对某人有用。这是萨姆·米勒答案的“模板化”版本。

#ifndef RANDOMCONSTANT_HH
#define RANDOMCONSTANT_HH

#include <boost/random.hpp>

boost::random::mt19937 g_randomConstantPrng(static_cast<unsigned int>(std::time(NULL) + getpid()));

template<typename T>
class RandomConstant
{
public:
    RandomConstant() { /* nothing */ }
    RandomConstant(T value) : _value(value) { /* nothing */ }
    RandomConstant(int low, int high)
    {
        boost::random::uniform_int_distribution<> dist(low, high);
        _value = dist(g_randomConstantPrng);
    }
    RandomConstant(double low, double high)
    {
        boost::random::uniform_real_distribution<> dist(low, high);
        _value = dist(g_randomConstantPrng);
    }
    T value() const { return _value; }

private:
    T _value;
};


template<typename T>
std::ostream&
operator<<(std::ostream& os, const RandomConstant<T>& foo)
{
    os << foo.value();
    return os;
}

template<typename T>
std::istream&
operator>>(std::istream &is, RandomConstant<T> &foo)
{
    std::string line;
    std::getline(is, line);
    if (!is) return is;

    const std::string::size_type comma = line.find_first_of( ',' );
    if (comma != std::string::npos)
    {
        const T low = boost::lexical_cast<T>( line.substr(0, comma) );
        const T high = boost::lexical_cast<T>( line.substr(comma + 1) );
        foo = RandomConstant<T>(low, high);
    }
    else
    {
        foo = RandomConstant<T>(boost::lexical_cast<T>(line));
    }

    return is;
}

#endif /* RANDOMCONSTANT_HH */
Run Code Online (Sandbox Code Playgroud)

使用方法如下:

namespace po = boost::program_options;
po::options_description desc;
desc.add_options()
    ("help", "show help")
    ("intValue", po::value<RandomConstant<int>>()->default_value(3), "description 1")
    ("doubleValue", po::value<RandomConstant<double>>()->default_value(1.5), "description 2")
;

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

if (vm.count("help")) {
    std::cerr << desc << std::endl;
    return EXIT_FAILURE;
}

int intValue = vm["intValue"].as<RandomConstant<int>>().value();
double doubleValue = vm["doubleValue"].as<RandomConstant<double>>().value();
Run Code Online (Sandbox Code Playgroud)