CLI11
CLI11 copied to clipboard
default value for std::pair
Following code does not work.
// (...)
float2 pre_translate;
app.add_option<float2, std::pair<float, float>>(
"--pre_translate", pre_translate, "translate before scaling (ie. to center the svg file)")
->default_val(std::pair<float, float>{0,0});
// (...)
It compiles, but when ran fails with:
terminate called after throwing an instance of 'CLI::ArgumentMismatch'
what(): --pre_translate: At least 2 required but received 1
zsh: IOT instruction (core dumped) ./a.out --pre_translate 0 0
float2
is interestingly not constructable from std::pair
but it works nevertheless.
It works correctly if I comment out the default_val
.
I'm pretty sure I'm doing something wrong. What's the correct method of specifying the default value?
It looks as if there is no to_string operation for a pair, so it is failing on the validation of the default_val.
That will probably take a bit to fix that issue in the meantime I would suggest
// (...)
float2 pre_translate;
app.add_option<float2, std::pair<float, float>>(
"--pre_translate", pre_translate, "translate before scaling (ie. to center the svg file)")->delimiter(',')
->default_str("0,0");
// (...)
basically add the delimiter then just use the default_str
to specify the default a little more directly
Basically what you did should ideally work, but it does require there to be some way to convert the value to a string, which in the case of pair doesn't exist yet. So until that is resolved you would need to use a bit of workaround.
Thank you for the swift response! I did a (different) workaround. I'm waiting for a fix to come in the future :)
Yeah, I also couldn't make it work with strings. :-/
using certs = std::pair<std::string, std::string>;
certs x;
op->add_option<certs>(
"--verify", x,
"[SIGNER SUBJECT] Verify the signature of the subject cert with the signer;\n"
"by default, 'root.crt' and 'leaf.crt' are used")
->delimiter(' ')
->default_str("root.crt leaf.crt");
When I ran it with an empty option --verify
it complains:
--verify: 2 required [TEXT,TEXT] missing
Run with --help for more information.
which doesn't make any sense since I have a default string value set, and BTW, [TEXT,TEXT]
also doesn't make sense since I changed the delimiter.
If I do not use the --verify
option at all, the x
is empty anyway.
It looks like the default with complex types does not work at all, or am I missing something in the code?
It looks like I didn't understand how the options works. The default value is assigned only if the option is not specified in the command line arguments. Otherwise, it is required to provide a value for the option.
And the ->default_str()
is not the right function to use, it has to be ->default_val()
std::string str;
op->add_option<std::string>(
"-s,--str", str, "description")
->default_val("abc");
But in this case, the logic behind default_val()
doesn't make any sense :/ since I can set the default value when I declare the variable std::string str("abc");
The default_val/str is used in a few cases
- When displaying a value in help - it can be derived from the variable used in the add_option as well.
- When querying the value of an option that was not given opt->results(output)
- When no arguments are passed to an option that allows arguments but is specified to allow none or some.
In your case if you want to use the default_str for case 3 then what is needed is
op->add_option(
"-s,--str", str, "description")
->default_val("abc")->expected(0,1);
now in the case of pair I think we are still working out all the edge cases with default values and multivalue non-vector inputs and things like that but it should look like this
using certs = std::pair<std::string, std::string>;
certs x;
op->add_option(
"--verify", x,
"[SIGNER SUBJECT] Verify the signature of the subject cert with the signer;\n"
"by default, 'root.crt' and 'leaf.crt' are used")
->delimiter(' ')
->default_str("root.crt leaf.crt")->expected(0,2);
the main thing you are missing is expected(0,max)
Thank you, @phlptp ! That was exactly what I was missing. Now, I understand what it means in the documentation expected(0,1) is the equivalent of making a flag.