gpt4 book ai didi

c++ - 使用 composing() 和 implicit_value() boost program_options 不是 "composed"

转载 作者:太空狗 更新时间:2023-10-29 21:26:23 26 4
gpt4 key购买 nike

在选项定义为 composing() 和 implicit() 的情况下,我遇到了 boost program_options (v1_49) 的问题。我的意图是像 perl 那样实现一个 -D 选项,这样您就可以执行 -D 或 -Dname 并多次使用它。我的 options_description 是:

(  "debug,D",
bpo::value<vector<string> >()
->composing()
->implicit_value(vector<string>(1,"1")),
"Set debug level."
),

这在大多数情况下似乎工作正常,但每当命令行上出现没有值的 -D 时,所有较早的值都会被删除,例如:

$ ./a.out -D abc -D 255 -D xyz
variables_map["debug"] = {"abc", "255", "xyz"}

$ ./a.out -D -D 255 -D xyz
variables_map["debug"] = {"1", "255", "xyz"}

$ ./a.out -D abc -D -D xyz
variables_map["debug"] = {"1", "xyz"}

$ ./a.out -D abc -D 255 -D
variables_map["debug"] = {"1"}

我想我明白为什么会发生这种情况,隐式值 {"1"} 替换现有 vector 而不是添加到它。我可以做些什么来让它工作,还是 boost::program_options 的限制?

最佳答案

这是一个不需要修改 boost 源的解决方法。如果将解析和存储任务分开,则可以修改中间 boost::program_options::parsed_options选项 vector 。 vector 的每个元素都包含 std::string key 和一个 std::vector<std::string>的值(value)。解决方法依赖于这样一个事实,即对于隐式值,值 vector 为空。如果我们扫描 parsed_options对于隐式值并显式地为它们分配一个值,那么它们就不会破坏同一键的先前值。这是工作代码:

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

namespace po = boost::program_options;

namespace std {
// This overload is needed to use composed options.
static std::ostream& operator<<(
std::ostream& os,
const std::vector<std::string>& v) {
os << '{';
BOOST_FOREACH(const std::string& s, v) {
if (&s != &*v.begin())
os << ", ";
os << '"' << s << '"';
}
os << '}';
return os;
}
}

int main(int argc, char *argv[]) {
po::options_description desc("Allowed options");
desc.add_options()
("debug,D",
po::value<std::vector<std::string> >()
->composing()
->implicit_value(std::vector<std::string>(1,"1")),
"Set debug level.");

// Just parse the options without storing them in the map.
po::parsed_options parsed_options = po::command_line_parser(argc, argv)
.options(desc)
.run();

// Implicit option values are empty, replace with default value.
BOOST_FOREACH(po::option& o, parsed_options.options) {
if (o.string_key == "debug" && o.value.empty())
o.value.push_back("1"); // default value is "1"
}

// Now store and earlier values aren't clobbered.
po::variables_map vm;
po::store(parsed_options, vm);
po::notify(vm);

std::cout << "variables_map[\"debug\"] = "
<< (vm.count("debug") ?
vm["debug"].as<std::vector<std::string> >() :
std::vector<std::string>())
<< '\n';
return 0;
}

这是相同的测试用例:

$ ./a.out -D abc -D 255 -D xyz
variables_map["debug"] = {"abc", "255", "xyz"}

$ ./a.out -D -D 255 -D xyz
variables_map["debug"] = {"1", "255", "xyz"}

$ ./a.out -D abc -D -D xyz
variables_map["debug"] = {"abc", "1", "xyz"}

$ ./a.out -D abc -D 255 -D
variables_map["debug"] = {"abc", "255", "1"}

关于c++ - 使用 composing() 和 implicit_value() boost program_options 不是 "composed",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11778153/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com