Allow rvalue references to be use with add_flag with no assignment (#1173)

I am starting to use CLI11 in a project and I came across an
inconvenience in code like this

```c++
const std::string description(std::format("description"));
app.add_flag("--flag", description);
```
As far as I can tell. I cannot directly use the description here. The
reason seems to be to distinguish between assignment and description. So
only `const std::string` or `const char*` and so on can be used here.
But a `const std::string &&` can not be used.

With the changes in the PR the code can also be written like this:
```c++
app.add_flag("--flag", std::format("description"));
```

The `add_flag` function can then be used with a const string or an
rvalue reference to a string.


A bit OT: I was a bit confused by this part of the existing comment ` if
a variable string is passed that variable will be assigned the results
from the flag` I think this might be wrong, but I am not sure.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Dominik Nussbaumer
2025-06-27 15:36:06 +02:00
committed by GitHub
parent 13658df9e1
commit 7a7ba4b9ca

View File

@@ -655,13 +655,15 @@ class App {
Option *add_flag(std::string flag_name) { return _add_flag_internal(flag_name, CLI::callback_t(), std::string{}); }
/// Add flag with description but with no variable assignment or callback
/// takes a constant string, if a variable string is passed that variable will be assigned the results from the
/// flag
/// takes a constant string or a rvalue reference to a string, if a variable string is passed that variable will be
/// assigned the results from the flag
template <typename T,
enable_if_t<std::is_const<T>::value && std::is_constructible<std::string, T>::value, detail::enabler> =
detail::dummy>
Option *add_flag(std::string flag_name, T &flag_description) {
return _add_flag_internal(flag_name, CLI::callback_t(), flag_description);
enable_if_t<(std::is_const<typename std::remove_reference<T>::type>::value ||
std::is_rvalue_reference<T &&>::value) &&
std::is_constructible<std::string, typename std::remove_reference<T>::type>::value,
detail::enabler> = detail::dummy>
Option *add_flag(std::string flag_name, T &&flag_description) {
return _add_flag_internal(flag_name, CLI::callback_t(), std::forward<T>(flag_description));
}
/// Other type version accepts all other types that are not vectors such as bool, enum, string or other classes