如何确定是否向 boost::program_options 提供了一个参数,或者是否使用了默认值?

How to determine if an argment was provided to boost::program_options, or if the default is used instead?

使用 boost::program_options,我需要设置 default_value 以便在帮助消息中显示默认值。但是,仍然需要知道是否应用了默认值或是否提供了参数。 (在某些情况下,如果提供了参数,逻辑将覆盖现有配置)。

可能的解决方案:


如何检测是否提供了参数,或者是否应用了默认值?

您的选项描述已损坏。让我们修复它们。我选择反对 ip_arg/port_arg 变量(注意你是如何让它们复制粘贴错误的)。

po::options_description options("Options");
options.add_options()
    ("ip", po::value<std::string>(&ip)->default_value("127.0.0.1"), "IP") //
    ("port", po::value<std::string>(&port)->default_value("80"), "Port")
 ;

现在您可以确定 port 始终已设置,因此 .count().contains() 是多余的。相反,询问地图条目是否已被默认:

if (vm["port"].defaulted()) {
    std::cout << "Port defaulted (" << port << ")\n";
} else {
    std::cout << "Port specified as " << port << "\n";
}

现场演示

Live On Coliru

#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <iostream>
namespace po = boost::program_options;
namespace fs = boost::filesystem;

int main( int argc, char* argv[])
{
    std::string ip;
    std::string port;

    po::options_description options("Options");
    options.add_options()
        ("ip", po::value<std::string>(&ip)->default_value("127.0.0.1"), "IP") //
        ("port", po::value<std::string>(&port)->default_value("80"), "Port")
     ;

    po::variables_map vm;
    try {
        using bs = po::command_line_style::style_t;

        boost::program_options::store(
            boost::program_options::command_line_parser(argc, argv)
                .options(options)
                .style(bs::long_allow_next | bs::allow_long | bs::allow_short |
                       bs::allow_dash_for_short | bs::long_allow_adjacent |
                       bs::short_allow_adjacent | bs::short_allow_next |
                       bs::allow_long_disguise)
                .run(),
            vm);

        po::notify(vm);
    } catch (...) {
        std::cerr << "Some error" << std::endl;
        return 1;
    }

    std::cout << options << std::endl;

    if (vm["port"].defaulted()) {
        std::cout << "Port defaulted (" << port << ")\n";
    } else {
        std::cout << "Port specified as " << port << "\n";
    }
}

打印例如

$ ./test --ip=192.168.1.2
Options:
  --ip arg (=127.0.0.1) IP
  --port arg (=80)      Port

Port defaulted (80)

$ ./test --port=8080
Options:
  --ip arg (=127.0.0.1) IP
  --port arg (=80)      Port

Port specified as 8080