gpt4 book ai didi

c++ - 相当于枚举类型的 boost::program_options::bool_switch

转载 作者:行者123 更新时间:2023-11-30 05:21:12 25 4
gpt4 key购买 nike

我有一个程序接受一组可用于选择某些行为的互斥标志。假设标志是 --csv , --xml--json分别选择 CSV、XML 和 JSON 作为输出格式。也可以通过单个 --format 来完成。然后将像在 --format=csv 中一样使用的标志, --format=xml--format=json具有相同的效果,但我不能也不想更改命令行界面。

我已经想出了一种方法来检查是否最多使用了这些选项中的一个,即它们的互斥性。我对此的解决方案不是最漂亮的,但我对这部分没意见。

离开这个检查,我的程序目前看起来像这样。

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

namespace po = boost::program_options;

enum output_formats {format_default, format_csv, format_xml, format_json};

int
main(int argc, char * * argv)
{
auto options = po::options_description{"Options"};
options.add_options()
("csv", "produce output in CSV format")
("xml", "produce output in XML format")
("json", "produce output in JSON format");
auto vm = po::variables_map{};
po::store(po::parse_command_line(argc, argv, options), vm);
po::notify(vm);
// Check that at most one of the options was passed (not shown here).
auto format = format_default;
if (vm.count("csv")) format = format_csv;
else if (vm.count("xml")) format = format_xml;
else if (vm.count("json")) format = format_json;
std::clog << "Output format: " << format << "\n";
}

它在工作,但我不喜欢 if , else if级联以找出用户传递的选项(如果有)。

我看过 boost::program_options::bool_switch 允许我定义将设置 bool 的标志它工作得很好。我想实现 enum_switch所以我可以将相同的技术应用于我的 enum并像这样重写代码。

int
main(int argc, char * * argv)
{
auto format = format_default;
auto options = po::options_description{"Options"};
options.add_options()
("csv", enum_switch(&format, format_csv), "produce output in CSV format")
("xml", enum_switch(&format, format_xml), "produce output in XML format")
("json", enum_switch(&format, format_json), "produce output in JSON format");
auto vm = po::variables_map{};
po::store(po::parse_command_line(argc, argv, options), vm);
po::notify(vm);
std::clog << "Output format: " << format << "\n";
}

我找到了 bool_switch 的实现在 Boost 中,它看起来像这样。

BOOST_PROGRAM_OPTIONS_DECL typed_value<bool>*
bool_switch(bool* v)
{
typed_value<bool>* r = new typed_value<bool>(v);
r->default_value(0);
r->zero_tokens();
return r;
}

因此,我实现了enum_switch像这样。

template <typename T>
boost::program_options::typed_value<T> *
enum_switch(T * dest, const T value)
{
auto tv = new boost::program_options::typed_value<T>{dest};
tv->default_value(value);
tv->zero_tokens();
return tv;
}

我注意到的第一件事是 Boost 提示我的 enum没有 >>运营商定义。好吧,我定义了一个,结果它从来没有被调用过。不幸的是,代码仍然不能按预期工作。如果我在没有选项的情况下调用我的程序,format将是 format_json如果我通过了,比如说,--xml ,我收到以下错误:

option '--xml' requires at least one argument

如果我通过 --xml 1我仍然遇到同样的错误,如果我使用 --xml=1然后我得到这个有趣的错误:

option '--xml' does not take any arguments

我缺少什么来使用我的 enum什么显然适用于 bool

最佳答案

尽管这个问题已经有几年了,但我现在发现了它,因为我也有同样的问题。

长话短说:您需要在 typed_value 实例上调用 implicit_value() 而不是 default_vaue() 来设置所需的格式值。

我还在 Program_options 代码中深入挖掘,以便更好地理解这个解决方案。来自 implicit_value() 的 api-doc :

Specifies an implicit value, which will be used if the option is given, but without an adjacent value. Using this implies that an explicit value is optional.

如果给出了一个隐式值并且没有其他显式参数,则该调用设置的值在 po::store()< 调用期间直接存储到 variables_map。否则,将调用 validate() 来检查给定的参数,然后再存储它们。一般验证函数总是需要至少 1 个参数,而 zero_tokens() 已经将最大值设置为 0。

对于 bool_switch() boost 已经提供了一个重载的 validate() 以正确的方式处理这种隐式情况(除了默认值 0 之外只有 1 个其他值).

关于c++ - 相当于枚举类型的 boost::program_options::bool_switch,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40305153/

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