boost::program_options bool_switch 多次使用
boost::program_options bool_switch used multiple times
我目前拥有的是
("someOption,s", po::bool_switch(&variable)->default_value(false), "")
我希望能够多次指定参数,每次出现都会切换此 bool 的值。
示例:
default value = false
./program -s
value == true
./program -s -s
value == false
./program -s -s -s
value == true
有没有办法多次使用 bool_switch 之类的东西,然后反复切换 on/off?我需要我的自定义类型和验证器吗?
也许我可以以某种方式允许多次指定选项,然后执行 vm.count("someOption") 并根据其值 (even/odd) 切换我的变量。但我更愿意在选项描述 (add_options) 中指定该行为,而无需稍后检查和修改值。
我真的花了 70 分钟尝试使用
让它工作
composing()
允许重复
- 带有
implicit_value({}, "")
自定义通知器的向量值虚拟选项(它们只运行一次)
- 自定义
notifier()
- 它们只 运行 一次,无论该选项出现和成功解析的频率如何
- 从
store
/notify
之后的 variables_map
获取向量值选项的大小。可悲的是,大小始终为 1,大概是因为 "compose" 实际上并没有在单个存储操作中组合(它仅在几个 运行 之间组合,所以不同的 sources 的选项,那么?)。
可悲的结论是,似乎没有办法。在这里,我惯常的口头禅得到了证实:"Simplicity Trumps Omniscient Design",我建议做同样的事情,但使用 https://github.com/adishavit/argh:
#include "argh.h"
#include <iostream>
namespace {
template <typename It>
size_t size(std::pair<It, It> const& range) { return std::distance(range.first, range.second); }
}
int main(int argc, char** argv) {
argh::parser p(argc, argv);
auto num_s = size(p.flags().equal_range("s"));
bool const variable = num_s % 2;
std::cout << "Repeated: " << num_s << ", effective " << std::boolalpha << variable;
std::cout << " (Command line was:";
while (*argv) std::cout << " " << *argv++;
std::cout << ")\n";
}
当 运行 使用各种命令行时,打印:
Repeated: 0, effective false (Command line was: ../build/sotest)
Repeated: 1, effective true (Command line was: ../build/sotest -s)
Repeated: 2, effective false (Command line was: ../build/sotest -s -s)
Repeated: 3, effective true (Command line was: ../build/sotest -s -s -s)
Repeated: 4, effective false (Command line was: ../build/sotest -s -s -s -s)
Repeated: 3, effective true (Command line was: ../build/sotest -s -s -s --other bogus)
这就是我到目前为止的接近程度。它看起来不是很优雅,更像是一种解决方法,我很乐意知道更好的 ("shorter") 解决方案。代码也可能存在一些问题,请随时纠正我。
目前它仅在 default 被视为 false 时才有效。我不知道如何从 true 开始,它需要以某种方式知道验证函数中的默认值。
它超出了这个问题的范围,希望在这里解决:
// my custom class
class BoolOption {
public:
BoolOption(bool initialState = false) : state(initialState) {}
bool getState() const {return state;}
void switchState() {state = !state;}
private:
bool state;
};
// two variables
BoolOption test1;
BoolOption test2;
// validate
void validate(boost::any &v, std::vector<std::string> const &xs, BoolOption*, long)
{
if (v.empty()) {
v = BoolOption(true); // I don't know how to assign default here so this works only when default is false
} else {
boost::any_cast<BoolOption&>(v).switchState();
}
}
optionsDescription->add_options()
("test1,t", po::value<BoolOption>(&test1)->default_value(BoolOption(true), "true")->zero_tokens(), "")
("test2,T", po::value<BoolOption>(&test2)->default_value(BoolOption(false), "false")->zero_tokens(), "")
;
// output result
cout << test1.getState() << endl;
cout << test2.getState() << endl;
这似乎工作正常,我可以这样调用它:
./program -t -t -T -t -T
它会切换参数。
我目前拥有的是
("someOption,s", po::bool_switch(&variable)->default_value(false), "")
我希望能够多次指定参数,每次出现都会切换此 bool 的值。
示例:
default value = false
./program -s
value == true
./program -s -s
value == false
./program -s -s -s
value == true
有没有办法多次使用 bool_switch 之类的东西,然后反复切换 on/off?我需要我的自定义类型和验证器吗?
也许我可以以某种方式允许多次指定选项,然后执行 vm.count("someOption") 并根据其值 (even/odd) 切换我的变量。但我更愿意在选项描述 (add_options) 中指定该行为,而无需稍后检查和修改值。
我真的花了 70 分钟尝试使用
让它工作composing()
允许重复- 带有
implicit_value({}, "")
自定义通知器的向量值虚拟选项(它们只运行一次) - 自定义
notifier()
- 它们只 运行 一次,无论该选项出现和成功解析的频率如何 - 从
store
/notify
之后的variables_map
获取向量值选项的大小。可悲的是,大小始终为 1,大概是因为 "compose" 实际上并没有在单个存储操作中组合(它仅在几个 运行 之间组合,所以不同的 sources 的选项,那么?)。
可悲的结论是,似乎没有办法。在这里,我惯常的口头禅得到了证实:"Simplicity Trumps Omniscient Design",我建议做同样的事情,但使用 https://github.com/adishavit/argh:
#include "argh.h"
#include <iostream>
namespace {
template <typename It>
size_t size(std::pair<It, It> const& range) { return std::distance(range.first, range.second); }
}
int main(int argc, char** argv) {
argh::parser p(argc, argv);
auto num_s = size(p.flags().equal_range("s"));
bool const variable = num_s % 2;
std::cout << "Repeated: " << num_s << ", effective " << std::boolalpha << variable;
std::cout << " (Command line was:";
while (*argv) std::cout << " " << *argv++;
std::cout << ")\n";
}
当 运行 使用各种命令行时,打印:
Repeated: 0, effective false (Command line was: ../build/sotest)
Repeated: 1, effective true (Command line was: ../build/sotest -s)
Repeated: 2, effective false (Command line was: ../build/sotest -s -s)
Repeated: 3, effective true (Command line was: ../build/sotest -s -s -s)
Repeated: 4, effective false (Command line was: ../build/sotest -s -s -s -s)
Repeated: 3, effective true (Command line was: ../build/sotest -s -s -s --other bogus)
这就是我到目前为止的接近程度。它看起来不是很优雅,更像是一种解决方法,我很乐意知道更好的 ("shorter") 解决方案。代码也可能存在一些问题,请随时纠正我。
目前它仅在 default 被视为 false 时才有效。我不知道如何从 true 开始,它需要以某种方式知道验证函数中的默认值。
它超出了这个问题的范围,希望在这里解决:
// my custom class
class BoolOption {
public:
BoolOption(bool initialState = false) : state(initialState) {}
bool getState() const {return state;}
void switchState() {state = !state;}
private:
bool state;
};
// two variables
BoolOption test1;
BoolOption test2;
// validate
void validate(boost::any &v, std::vector<std::string> const &xs, BoolOption*, long)
{
if (v.empty()) {
v = BoolOption(true); // I don't know how to assign default here so this works only when default is false
} else {
boost::any_cast<BoolOption&>(v).switchState();
}
}
optionsDescription->add_options()
("test1,t", po::value<BoolOption>(&test1)->default_value(BoolOption(true), "true")->zero_tokens(), "")
("test2,T", po::value<BoolOption>(&test2)->default_value(BoolOption(false), "false")->zero_tokens(), "")
;
// output result
cout << test1.getState() << endl;
cout << test2.getState() << endl;
这似乎工作正常,我可以这样调用它:
./program -t -t -T -t -T
它会切换参数。